Java using scanner with try-with-resources

孤街浪徒 提交于 2019-12-06 01:12:39

Adding a little bit more detail to my comments

A try-with block is defined as follows:

try(...) {
   ...
}

where the argument in parenthesis needs to be an instance of java.lang.AutoCloseable. An example is the class java.io.InputStream, which is also the class for System.in.

A try-with attempts to automatically close its provided resource, once the block is left. Depending on the used resource, it closes all its own child resources as well.

Taking your example, you have try(Scanner scanner = new Scanner(System.in)), which uses Scanner as resource. The scanner itself uses System.in as resource. Once the try block is left (when } is reached) it tries to close its resources, which is the Scanner instance. This instance also tries to close its resource, the System.in.

Once System.in is closed, you can't get any input from the console anymore (at least not with some additional work, I think...).

Concretely, in your second example:

while (!input.equals("q")) {
    try(Scanner scanner = new Scanner(System.in)){
            ...
    }  // <--- The block is left, scanner is closed, System.in is closed
} // <-- start a new iteration

Here after just one iteration, System.in gets closed. Sure, you create a new Scanner in the next iteration, but System.in remains closed, that's why you get your exception in this case.

Your third example:

try(Scanner scanner = new Scanner(System.in)){
    while (!input.equals("q")) {
        ...
    } // <-- start a new iteration, while still in the same try block
} // <-- only after the while, your resources are closed

Here you're looping your while, while still being inside try. So no resource gets closed, until you leave while and try. That means, the one Scanner remains intact and with it the one System.in. This allows you to keep reading from the console until you're done looping.

Try this:

   String input = "";
   try (Scanner scanner = new Scanner(System.in)) {
       while (!input.equals("q")) {
           System.out.print("Input: ");
           input = scanner.nextLine();
           System.out.println("Input was: " + input);
       }
   }

You can use every class thats implements Closeable or AutoCloseable in try-with-resources, When code reaches the end of the try call, It call close() function of the Scanner class in our example.

i run some tests and add the catch block into your code.here's the code

public static void main(String[] args) {
    String input = "";
    while (!input.equals("q")) {
        try(Scanner scanner = new Scanner(System.in)){
            System.out.print("Input: ");
            input = scanner.nextLine();
            System.out.println("Input was: " + input);
        }
        catch (Exception e) {
            e.printStackTrace();
        }            
    }
}

when add the catch block,there are 2 kinds of results 1,only inputs q, works as expected 2,inputs any other String, exception

Input: java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1585)
at rews.pub.Test.main(Test.java:11)

when added the catch block, we will see that the program won't stop, because of the while loop

here is another easier test

public class Test {
public static void main(String[] args) {
    String input = "";
    Scanner scanner = new Scanner(System.in);
    System.out.println("inout--1---");
    input = scanner.nextLine();
    scanner.close();

    Scanner scanner2 = new Scanner(System.in);
    System.out.println("inout--2---");
    input = scanner2.nextLine();
    scanner2.close();

}

}

and it goes same exception

inout--1---
11
inout--2---
Exception in thread "main" java.util.NoSuchElementException: No line  found
at java.util.Scanner.nextLine(Scanner.java:1585)
at rews.pub.Test.main(Test.java:15)

here's my opinion. in the end of first run, try()block will close the resource which is in the block, means we close the system.in system.in is a object of inputSteam,and system.in is final and static, we can't open it again like 'new Scanner(System.in)'

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!