问题引入
Java商店作业不同函数里需要获取用户输入,用Scanner
的时候,出现了异常java.util.NoSuchElementException
作业中代码模式如下,func1
和func2
中都使用Scanner
并关闭它。然后在main中依次调用func1
和func2
,func2
产生异常。说func1
和func2
其实不合适,应该加个括号……..懒得加了
1 | //Demo.java |
异常产生原因
func1
中sc.close();
语句关闭了Scanner
,func2
中使用Scanner
产生异常
因为System.in
是System
类的静态成员,所以不同Scanner
对象内的in是同一个
in`
func1
和func2
中都用System.in
创建了Scanner
func1
打开Scanner
后将其关闭,这里间接地将System.in
也关闭了
func1
结束后运行func2
,这时再调用nextInt
,在System.in
已经关闭了的情况下,不能读取到任何数据,就会产生 java.util.NoSuchElementException
解决方法
系统资源一旦释放就不能再开启了,所以只有确定不在使用系统的时候,才能将流关闭
所以应该在整个程序结束时释放Scanner
等资源,而不是某个函数中每次使用Scanner
等资源后都释放一次
问题引入中的代码只是个模式,上边的两句话用在作业实际代码里就好了
代码分析
Scanner()
创建Scanner
对象代码为Scanner sc=new Scanner(System.in);
构造函数源码如下
1 | public Scanner(InputStream source) { |
可看出是调用了另外一个构造函数,继续查看源码
1 | private Scanner(Readable source, Pattern pattern) { |
至少知道了Scanner
内部还是用到了流,算是对流进行了封装吧,使用起来更方便一些
close()
调用语句为sc.close();
,查看close()
源码,如下
1 | public void close() { |
可以知道关闭Scanner
的时候,((Closeable)source).close();
把System.in
关闭了
关闭后下次想再使用就当然有错了~(除非构造函数里还再把in
给打开,但这样也不太合理)
其实如果还可以再仔细看看Scanner
的构造方法,和Scanner
的next()
,能力有限,点到为止
作者:@臭咸鱼
本文为作者原创,转载请注明出处:https://chouxianyu.github.io/2018/11/03/java.util.NoSuchElementException/#more
欢迎转发和评论