Usando try-with-resources com System.in [duplicado]
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
Eu não recomendaria ter vários Scanner
objetos 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 Scanner
objeto global que envolva System.in
e, 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.
como faço para evitar isso?
Não feche o Scanner
objeto, ou seja, não use try-with-resources em um Scanner
que 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:
