Java编译报错:Exception in thread “main“ java.util.NoSuchElementException(剖析原因理解及解决方法)

报错原因:程序中调用Scanner.close()一次之后,在后续的代码中使用了输入流读取方法.

先上出错代码:

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()方法放在程序末尾.

在我寻找问题原因的过程中最让我受益的文章:博客园----自律即自由

你可能感兴趣的:(java)