【发布时间】:2020-12-11 20:06:09
【问题描述】:
所以我的 IDE 会抱怨如果我没有将 Scanner 包含在 try with 块中,但是如果我这样做而不是在它应该关闭时关闭它(一旦 win = true),它会关闭系统。在流中,我该如何防止呢?
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);
}
【问题讨论】:
-
这能回答你的问题吗? Close Scanner without closing System.in
-
我在谷歌搜索中看到了这个,但想也许会有更好的解决方案?当然,为我认为是常见问题的问题创建自己的课程并不是唯一的解决方案。
-
我同意这并不理想,但它似乎是唯一的解决方案(考虑到您想彻底关闭资源)。您当然可以通过将防止关闭的包装类移动到单独的文件或使用库解决方案来保持代码更清洁,就像 here 所做的那样。我认为这是 JDK 中的一个设计缺陷,
close'ing 流通常会在其包装的流上调用close。 -
@Reizo “考虑到你想彻底关闭你的资源”。除了
System.in不属于你,所以你不应该“干净地关闭”它,即使你把它包裹在什么东西里,比如Scanner。 -
@Reizo 包装流关闭底层流的事实当然不是设计缺陷。如果他们不这样做,您将无法创建像
new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))))这样的链式流,像这样手动或使用其中一些类提供的便利助手。close()在所有情况下都必须调用,除非在包装System.in时。让这成为例外,并非所有其他时间都使用包装器。