问题
earlier today I asked how to re-try/catch input mismatch exception without getting caught by infinite loop
but it's two procedures process, at first the game will ask the user for the size of the grid and later after the launch it will ask him either to set up a flag or step over a cell(if mine the game will be over else it will print out the number of surrounding mines), but I get some weird errors the code:
int gridSize = 0;
try (Scanner scanner = new Scanner(System.in)) {
System.out.println("how much the size of the grid do you want");
while (!scanner.hasNextInt()) {
System.err.println("Try again, this time with a proper int");
scanner.next();
}
gridSize = scanner.nextInt();
}
MinesWeeper grid = new MinesWeeper(gridSize);
grid.printOut();
int choice = 0;
try (Scanner scanner = new Scanner(System.in)) {
System.out.println("1-to step over a cell\n2-to set a flag on the cell");
while (!scanner.hasNextInt()) {
System.err.println("Try again, this time with a proper int");
scanner.next();
}
choice = scanner.nextInt();
}
boolean Continue = true;
while (Continue) {
switch (choice) {
case 1:
if (grid.chooseCell(1)) {
Continue = false;
}
break;
case 2:
grid.chooseCell(2);
break;
}
}
errors:
how much the size of the grid do you want
3
A B C
Try again, this time with a proper int
1 * * *
Exception in thread "main" java.util.NoSuchElementException
2 * * *
at java.util.Scanner.throwFor(Scanner.java:862)
3 * * *
1-to step over a cell
at java.util.Scanner.next(Scanner.java:1371)
at Array.Main.main(MinesWeeper.java:188)
2-to set a flag on the cell
the weird thing that it prints exceptions messages between my printing statements(the grid is one statement, instructions are one too)
when I made my search I found that I can't use two scanners on the same spot, but how can I separate them if they initialized on try with resources
回答1:
This:
try (Scanner scanner = new Scanner(System.in)) {
// ...
}
is a try-with-resources block. When the block finishes executing, it will call scanner.close()
.
The problem with that, for your use case, is that the Scanner, in turn, invokes System.in.close()
. Once a stream has been closed, you can't read from it again, so you will get an exception when you try to create another Scanner reading from System.in
subsequently.
The most trivial fix to your code is to merge the two try-with-resources blocks, and reuse the same Scanner, so you don't close it in between. There is no good reason to have two separate scanners anyway.
But actually, you shouldn't be using try-with-resources at all.
The general rule is not to close a stream that you don't own, which roughly translates to don't close a stream you didn't open, given that Java has no concept of "ownership". You didn't open System.in
, the JVM did.
You don't know what else in your program is relying on it continuing to be open. If you do close such a stream, you mess up the state of the stream for future readers of the stream.
Now, you may think that you need to use twr, because your IDE flags a resource leak warning on the Scanner otherwise. In general, you may want to close a Scanner; in this specific case, you do not. Ignore (or suppress) that warning, if that is why you are using twr.
来源:https://stackoverflow.com/questions/52907500/how-to-use-two-scanners-on-one-method