问题
Why would the following code give me a runtime error? It gives me a NoSuchElementException when the method is called the second time. It works fine if I delete the call to stdin.close(), but then Eclipse gives a warning that the resource is not closed.
Code:
import java.util.Scanner;
public class st {
public static void main(String[] args) {
System.out.println("First call");
getInt("Enter first int (1-10): ");
System.out.println("Second call");
getInt("Enter second int (1-10): ");
}
/**
* Reads an integer number from the keyboard.
*
* @param prompt the string to display as a prompt.
* @return the integer number entered at the keyboard.
*/
public static int getInt(String prompt) {
Scanner stdin = new Scanner(System.in);
System.out.print(prompt);
int val = stdin.nextInt();
stdin.close();
return(val);
}
}
// END
Output:
>java st
First call
Enter first int (1-10): 5
Second call
Enter second int (1-10): Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at st.getInt(st.java:24)
at st.main(st.java:9)
>
Version:
>java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
>
Thanks
Brian
回答1:
AS @MikePrecup says, when you close the first Scanner (stdin), you are also closing System.in, therefore the second Scanner can no longer read from it and a NoSuchElementException is thrown.
However, I would suggest another option: use a single scanner declaring it as a class variable.
public class st {
private static Scanner stdin = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("First call");
getInt("Enter first int (1-10): ");
System.out.println("Second call");
getInt("Enter second int (1-10): ");
}
/**
* Reads an integer number from the keyboard.
*
* @param prompt the string to display as a prompt.
* @return the integer number entered at the keyboard.
*/
public static int getInt(String prompt) {
System.out.print(prompt);
int val = stdin.nextInt();
stdin.close();
return(val);
}
}
// END
回答2:
The problem is that closing stdin also closes the underlying stream, which is, in this case, System.in. Hence, you won't be able to get any more input from it. You'll need to prevent it from closing. The easiest option is probably to wrap System.in with a CloseShieldInputStream.
来源:https://stackoverflow.com/questions/17256945/using-a-java-util-scanner-from-within-a-method-causes-a-runtime-error