Использование try-with-resources с System.in [дубликат]
Итак, моя IDE жалуется, если я не включу сканер в блок try with, но если я сделаю это таким образом, вместо того, чтобы закрыть его, когда он должен был закрыться (однажды win = true), он закрывает поток System.in, как мне предотвратить это?
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);
}
Ответы
Я бы рекомендовал не использовать несколько Scanner
объектов, обертывающих один и тот же входной поток. (в данном случае System.in
) Причина в том, что сканеры могут потреблять и буферизовать данные из базового потока. Это означает, что в некоторых случаях данные могут быть потеряны. Вы можете прочитать об этом подробнее в этом вопросе .
Здесь вам может сойти с рук, и в этом случае вам просто не следует закрывать объект Scanner, не помещая его в try-with-resources. В этом случае вы можете подавить предупреждение с помощью @SuppressWarnings("resource")
. Однако это плохая практика.
Вместо этого я бы рекомендовал создать один глобальный Scanner
объект, который обтекает его System.in
, а затем передать его этому методу в качестве параметра вместо создания нового сканера в каждом методе, требующем ввода.
как мне предотвратить это?
Не закрывайте Scanner
объект, то есть не используйте try-with-resources для Scanner
упаковываемого объекта System.in
.
Вместо этого примите предупреждение и скройте его, поскольку это особое исключение из обычных правил "ресурсов":
@SuppressWarnings("resource")
Scanner keyboard = new Scanner(System.in);
К вашему сведению: я использую Eclipse IDE, и «Окружить с помощью try-with-resources» - это только первый вариант для устранения предупреждения:
