Java使用带有try-with-resources的扫描仪 [英] Java using scanner with try-with-resources

查看:133
本文介绍了Java使用带有try-with-resources的扫描仪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个版本的Java代码,它们可以获取用户输入,直到用户键入"q"为止 版本1:

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);
        }
    }
}

版本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);
            }
        }
    }
}

版本1可以正常工作,但是版本2不能正常工作. 那是在第一次阅读用户输入后,它会产生一个错误

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)

我的猜测是,因为版本2使用try资源,所以它在使用后关闭了扫描仪,这会导致错误?

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

谢谢您的帮助!

[更新] 版本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);
            }
        }
    }
}

第3版有效.但是,为什么版本3没问题,而版本2没问题?

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

推荐答案

在我的评论中添加更多细节

try-with块的定义如下:

try(...) {
   ...
}

其中括号中的参数必须是 java.lang.AutoCloseable .一个例子是类 java.io.InputStream ,这也是System.in的类.

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.

一旦离开该块,try-with尝试自动关闭其提供的资源.根据使用的资源,它也会关闭所有自己的子资源.

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.

以您的示例为例,您有try(Scanner scanner = new Scanner(System.in)),它使用Scanner作为资源.扫描仪本身使用System.in作为资源.一旦离开try块(到达}时),它将尝试关闭其资源,即Scanner实例.此实例还尝试关闭其 资源System.in.

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.

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

在这里,仅经过一次迭代,System.in就关闭了.当然,您在下一次迭代中创建了一个新的Scanner,但是System.in 仍处于关闭状态,这就是为什么在这种情况下会出现异常的原因.

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.

您的第三个示例:

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

在这里,您正在循环while,而仍在里面 try.因此,除非您离开whiletry,否则不会关闭任何资源.这意味着,一个Scanner保持不变,而一个System.in保持不变.这样,您就可以继续从控制台读取内容,直到完成循环为止.

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.

这篇关于Java使用带有try-with-resources的扫描仪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆