Usando try-with-resources com System.in [duplicado]

Dec 12 2020

Portanto, meu IDE está reclamando se eu não incluir o Scanner em um bloco try with, mas se eu fizer isso desta forma em vez de fechá-lo quando deveria ser fechado (uma vez que win = true), ele fecha o fluxo System.in, como faço para evitar isso?

public final void turn() {
    System.out.println("Enter your next move!");
    try (Scanner keyboard = new Scanner(System.in)) {
        final String move = keyboard.nextLine();
        if (move.isEmpty()) {
            won = true;
            return;
        }
        if (!validateFormat(move)) {
            System.out.println("Invalid format, try again.");
            return;
        }
        String[] moveAr;
        try {
            moveAr = move.split(",");
        } catch (PatternSyntaxException e) {
            System.out.println(e.getMessage());
            return;
        }
        try {
            validFields(moveAr);
        } catch (InvalidTurnException e) {
            System.out.println(e.getMessage());
            return;
        }
        final char colour = spielFeld.getField(getColumn(moveAr[0].charAt(0)),Character.getNumericValue(moveAr[0].charAt(1)) - 1).getColour();
        for (final String string : moveAr) {
            final int line = Character.getNumericValue(string.charAt(1)) - 1;
            final int column = getColumn(string.charAt(0));
            spielFeld.cross(column,line);
            final int columni = getColumn(string.charAt(0));
            if (spielFeld.columnCrossed(columni)) {
                points += crossedValues(string.charAt(0));
            }
        }
        if (spielFeld.colourComplete(colour)) {
            points += COLOUR_POINTS;
            coloursCrossed++;
        }
        if (coloursCrossed >= 2) {
            won = true;
        }
    }
    System.out.println("Momentane Punkte: " + points);
}

Respostas

a.deshpande012 Dec 12 2020 at 03:19

Eu não recomendaria ter vários Scannerobjetos envolvendo o mesmo fluxo de entrada. (neste caso, System.in) A razão para isso é porque os Scanners podem consumir e armazenar em buffer os dados do fluxo subjacente. Isso significa que, em alguns casos, os dados podem ser perdidos. Você pode ler mais sobre isso nesta questão .

Você pode conseguir se safar aqui; nesse caso, você simplesmente não deve fechar o objeto Scanner não envolvendo-o em um try-with-resources. Nesse caso, você pode suprimir o aviso com @SuppressWarnings("resource"). No entanto, esta é uma prática ruim.

Em vez disso, eu recomendaria criar um único Scannerobjeto global que envolva System.ine, em seguida, passá-lo para esse método como um parâmetro em vez de criar um novo scanner em cada método que requer entrada.

Andreas Dec 12 2020 at 03:16

como faço para evitar isso?

Não feche o Scannerobjeto, ou seja, não use try-with-resources em um Scannerque está empacotando System.in.

Em vez disso, aceite o aviso e oculte-o, pois é uma exceção especial às regras normais de "recurso":

@SuppressWarnings("resource")
Scanner keyboard = new Scanner(System.in);

Para sua informação: Estou usando o IDE Eclipse, e "Surround with try-with-resources" é apenas a primeira opção para corrigir o aviso: