我有两个版本的Java代码,用户输入直到用户输入“q” 版本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无法按预期工作。 这是第一次读取用户输入后,会产生错误
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 with resource所以它在使用后关闭扫描程序并导致错误?
提前感谢您的帮助!
[更新] 第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还不行?
答案 0 :(得分:3)
在我的评论中添加更多细节
try-with
块的定义如下:
try(...) {
...
}
其中括号中的参数需要是java.lang.AutoCloseable
的实例。一个例子是类java.io.InputStream
,它也是System.in
的类。
一旦剩下块,try-with
会尝试自动关闭其提供的资源。根据使用的资源,它还会关闭所有自己的子资源。
举个例子,你有try(Scanner scanner = new Scanner(System.in))
,它使用Scanner
作为资源。扫描程序本身使用System.in
作为资源。在离开try
块时(到达}
时),它会尝试关闭其资源,即Scanner
实例。此实例还尝试关闭其资源System.in
。
关闭System.in
后,你再也无法从控制台获得任何输入(至少没有额外的工作,我认为......)。
具体地说,在你的第二个例子中:
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
仍然关闭,这就是您在这种情况下获得异常的原因。
你的第三个例子:
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
就是 $date_query[] = array(
'after' => get_query_var( 'timestart'),
'before' => get_query_var('timeend')
);
$date_query['relation'] = 'AND';
$date_query['inclusive'] = true;
。这允许您在完成循环之前继续从控制台读取。
答案 1 :(得分:0)
试试这个:
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);
}
}
您可以在try-with-resources中使用实现Closeable
或AutoCloseable
的每个类,当代码到达try调用的末尾时,它调用close()
函数Scanner
我们的例子中有1}}类。
答案 2 :(得分:0)
我运行一些测试并将catch块添加到您的代码中。这是代码
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();
}
}
}
添加catch块时,有2种结果 1,只输入q,按预期工作 2,输入任何其他String,异常
Input: java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1585)
at rews.pub.Test.main(Test.java:11)
当添加catch块时,我们将看到该程序因为while循环而不会停止
这是另一个更容易的测试
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();
}
}
它也是同样的例外
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)
这是我的看法。 在第一次运行结束时,try()块将关闭块中的资源,意味着我们关闭system.in system.in是inputSteam的一个对象,system.in是final和static,我们不能像新的Scanner(System.in)&#39;
一样再次打开它。