Java使用带有try-with-resources的扫描仪 [英] Java using scanner with 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
.因此,除非您离开while
和try
,否则不会关闭任何资源.这意味着,一个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屋!