How do I close a scanner in java?

2019-05-17 09:06发布

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?

5条回答
我欲成王,谁敢阻挡
2楼-- · 2019-05-17 09:30

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.

查看更多
迷人小祖宗
3楼-- · 2019-05-17 09:37

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.

查看更多
forever°为你锁心
4楼-- · 2019-05-17 09:42

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楼-- · 2019-05-17 09:44

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();
}
查看更多
看我几分像从前
6楼-- · 2019-05-17 09:47

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.

查看更多
登录 后发表回答