Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
815 views
in Technique[技术] by (71.8m points)

try catch - Java using scanner with try-with-resources

I have two versions of Java code that gets user input until user types "q" Version 1:

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

Version 2:

public class Test {
    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);
            }
        }
    }
}

Version 1 works as expected but version 2 does not work as expected. That is after reading user input for the first time, it produces an error

Input: 12
Input was: 12Exception in thread "main" 
Input: java.util.NoSuchElementException: No line found
    at java.util.Scanner.nextLine(Scanner.java:1540)
    at RealEstateCompany.main(RealEstateCompany.java:115)

My guess is since version 2 uses try with resource so it closes the scanner after being used and that is causing an error?

Thank you for your help in advance!

[Update] Version 3:

public class Test {
    public static void main(String[] args) {
        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);
            }
        }
    }
}

Version 3 works. However, why version 3 is ok and version 2 is not ok?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...