软件构造——实验二新知识(二)

在完成实验的过程中,见到了从未见过的异常:NoSuchElementException。
使用情况是方法A调用方法B,也调用方法C,在B和C中都使用了Scanner,并且都进行了关闭。情况和下面的情况大致相同。

public class testScanner{
class testScanner{
	public static void main(String[] args) {
		testScanner test = new testScanner();
		test.method1();
		test.method2();
	}
	public void method1() {
		Scanner inScanner = new Scanner(System.in);
		inScanner.next();
		inScanner.close();
	}
	public void method2() {
		Scanner inScanner = new Scanner(System.in);
		inScanner.next();
		inScanner.close();
	}
}

错误提示如图所示:
在这里插入图片描述
查阅博客(博客园)之后得知,是因为System.in是静态的,当前类中所有System对象共享,在使用close()方法时,会同时关闭Scanner和System.in,而System.in关闭后尝试再次打开得到的值是-1,当第二个函数再次想实例化Scanner时就会抛出NoSuchElementException异常。
在博客园中“IT学习者-螃蟹”的讲解中,看到了这样一段源码:

在Scanner 的readinput方法里面有以下代码:
try {
n = source.read(buf);
} catch (IOException ioe) {
lastException = ioe;
n = -1;
}

if (n == -1) {
sourceClosed = true;
needInput = false;
}
Scanner的next方法中有以下代码:
if (needInput)
readInput();
else
throwFor();

throwFor中的部分代码:
skipped = false;
if ((sourceClosed) && (position == buf.limit()))
throw new NoSuchElementException();
else
throw new InputMismatchException();

梳理一下这个过程:第一次调用method1时,将inScanner关闭,同时也关闭了System.in,因为这个是静态的,所以在这个类中,就被彻底关闭了。之后method2尝试利用其进行读入,因为已经关闭,则读到-1,设置sourceClosed = true;
needInput = false。之后执行throwFor(),position 是当前读取的内容在缓冲区中位置,因为读取的是-1,因此position =0,而buf.limit()也等于0,因此就执行了throw new NoSuchElementException()。

发布了13 篇原创文章 · 获赞 2 · 访问量 580

猜你喜欢

转载自blog.csdn.net/qq_43887432/article/details/105313871