How do I close a scanner in java?

2019-05-17 08:51发布

问题:

When ever I run the following code,

private static String input(String Message){
    Scanner input_scanner = new Scanner(System.in);
    System.out.print("\n" + Message);
    String string = input_scanner.nextLine();
    input_scanner.close();
    return string;
}

I get this error:

Exception in thread "main" java.util.NoSuchElementException: No line found
    at java.util.Scanner.nextLine(Unknown Source)
    at main.learn.input(learn.java:25)
    at main.learn.main(learn.java:13)

I figured out it was something to do with the line input_scanner.close(); but when I remove it, I get warnings saying:

Resource leak: "input_scanner" is never closed"

Is there anyway I can stop the errors from happening and get rid of the warnings?

回答1:

You should check if you have data to consume for Scanner using hasNextLine api which you could do like:

String string = "";
if (input_scanner.hasNextLine()) {
    string = input_scanner.nextLine();
}


回答2:

Well, first I recommend you to use the API to understand the exceptions that Java shows you.

Read this for further information about NoSuchElementException:
http://docs.oracle.com/javase/7/docs/api/java/util/NoSuchElementException.html

When you use scanner, stringTokenizer, iterators... you have to verify that you have more elements to read before you try read them. If you don't do that, you can get that type of exceptions.

private static String input(String Message){
    Scanner input_scanner = new Scanner(System.in);
    System.out.print("\n" + Message);
    if (input_scanner.hasNextLine()){
       String string = input_scanner.nextLine();
    }
    input_scanner.close();
    return string;

If you want to read more than one line, use while (input_scanner.hasNextLine())

Your mistake is about the keyboard input. Read this to understand if you are doing well that part: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#hasNextLine%28%29

PS: is recommended to close your scanner with input_scanner.close() when you have finished with it.



回答3:

use try-with-resources to guarantee that your scanner closes regardless if any exceptions occur.

try (Scanner input_scanner = new Scanner(System.in)) {
   .
   .
   .
}

You can use this with anything that implements AutoCloseable, and it's much better than requiring a bunch of try-catch for exceptions thrown when closing.



回答4:

Actually, since you are using Scanner for System.in, this means it is a blocking call that will hold until it receives the first input from the user. Being a local variable, you don't really need to close the scanner, and you definitely don't need a while loop for hasNextLine();

private static String input(String Message){
Scanner input_scanner = new Scanner(System.in);
System.out.print("\n" + Message);
String string = input_scanner.nextLine();
return string;


回答5:

A scanning operation may block waiting for input. If no inputs are received then the scanner object does not having to read which makes the Exception to thrown since it does not find the element that need to be close. By verifying does the stream consist anything that could be read by scanning object will helps you in getting this kind of exception.