Java中经常会使用Scanner类的来接收从键盘的数据输入,使用完毕后,要关闭扫描器,因为System.in属于系统IO流,一旦打开,它一直在占用资源,因此使用完毕后切记要关闭。但如果对其中一些细节不了解,也会引发异常。
示例代码如下:
/**
* Scanner的关闭问题
* @author Jack
* @date 2018-10-08
*/
public class ScannerCloseDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.next();
sc.close();
Scanner in = new Scanner(System.in);
in.next();
}
}
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at com._520it.chapter04.ScannerCloseDemo.main(ScannerCloseDemo.java:11)
异常原因分析:
在创建完Scanner类对象sc后,从键盘接收一次输入后,调用close方法关闭输入流,然后再创建一个新的Scanner对象,这时尽管编译通过,但是运行时会出现异常。
这是因为创建的sc和in对象都是通过System.in封装而来的,虽然是两个独立的对象,但是用的是同一个输入流(System.in)。当调用in.close()时,实际上相当于关闭了System.in这个输入流。因此对于第二次创建的in来说,System.in已经被关闭了,就无法正常创建出对象,从而会产生java.util.NoSuchElementException异常。
再进一步查看Java的API文档后发现:
可以看出,in字段被static所修饰,是属于类本身的,因此当调用sc.close()方法后,就不能再通过new Scanner(System.in)来创建Scnaner对象了。
解决方案:
在包含主方法的类中创建Scanner对象,然后再调用其他方法,在代码的最后调用close()来关闭输入流。