先上出错代码:
public class Test1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
scanner.next();
scanner.close();
Scanner scanner2 = new Scanner(System.in);
scanner2.next();
System.out.print(2);
scanner2.close();
}
错误的原因主要与我们创建Scanner
对象时构造器Scanner()
括号里的参数System.in
有关,查看原始类文件发现:System.in
被设置为了final
型: public static final InputStream in = null;
(为什么图片自动添加了水印,不知道怎么去除,不好意思)因此它在整个程序中只会有一个值(只能被初始化一次)。也就是说不管后面创建多少个Scanner类对象,每次都是返回同一个InputStream流,只不过,创建新的Scanner对象后会开辟一个并列的输入流,下面将证明这一点:
//代码一:(作为参照的代码)
Scanner scanner = new Scanner(System.in);
String q = scanner.next();
String w = scanner.next();
System.out.print(q + w);
scanner.close();
//输入12 34回车
//输出1234
//代码二:
Scanner scanner = new Scanner(System.in);
String q = scanner.next();
Scanner scanner2 = new Scanner(System.in);
String w = scanner2.next();
System.out.print(q + w);
scanner2.close();
scanner.close();
//输入12 34回车,输入56回车(两次回车)
//输出:1256(说明两个输入流是并列的)
尽管如此,这些Scanner对象仍然来自一个System.in,就相当于黄河的源头只有一个,但流淌的时候,我们可以创建多个分支河流,但源头一旦关闭,所有河流分支就不会有流.所以一旦关闭流后,后面的对象所用的流就都将是关闭状态,所以在顶部的出错代码中,当第一次调用close()关闭流之后的代码中尽管又创建了一个Scanner对象,调用Scanner.next()方法还是会报错:
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1478)
at Java征程/war1.Test1.main(Test1.java:16)
在知道了错误的原因的情况下,想要解决问题就很简单了,就很游刃有余了,只要确保关闭流之后不会再调用输入流读取方法就可以了,通常把close()方法放在程序末尾.
在我寻找问题原因的过程中最让我受益的文章:博客园----自律即自由