由于提前关闭Scanner对象引起的NoSuchElementException异常

最近实验过程中遇到了NoSuchElementException异常,查询各种资料并经过实践发现是由于提前关闭Scanner引起的异常。
考虑如下代码:

import java.util.Scanner;

public class TestScanner {

    public static void test() {
        Scanner b = new Scanner(System.in);
        System.out.println("test:");
        int number = b.nextInt();
        System.out.println("test: " + number);
        b.close();
    }

    public static void main(String[] args) {
        Scanner a = new Scanner(System.in);
        test();
        System.out.println("main:");
        int number = a.nextInt();
        System.out.println("main: " + number);
        a.close();
    }
}

main函数中调用test函数,让用户输入两个int型数据,然后打印出来。

但是运行后却发现在输入第一个数但还未输入第二个数时就抛出了NoSuchElementException异常。

NoSuchElementException异常
JDK文档中对于此异常的描述如下:

Thrown by various accessor methods to indicate that the element being requested does not exist.

翻译成通俗的语言就是指在访问不存在的元素时会抛出此异常,结合上面的简单程序,我们很容易想到可能是Scanner对象不存在引起的异常(其他部分十分简单,可能性不大)。
那么为什么会造成此异常呢?难道是main中的Scanner对象a和test中的Scanner对象b相互影响?

实际上问题出在System.in上。

查询JDK文档后可发现,Scanner类的构造方法接收一个InputStream对象:public Scanner​(InputStream source);而System.in是定义在System类中的一个InputStream类型的常量(public static final InputStream in),static意味着“只有一个”,所以任何通过new Scanner​(System.in)构造出的Scanner对象都和同一个InputStream对象System.in相关联。
因此关闭任何一个Scanner对象,其他Scanner对象也关闭了。表现在上述事例代码中即是:test函数中关闭了Scanner对象b,使得main函数中的Scanner对象a也关闭了,再次访问a进行输入就抛出了NoSuchElementException异常。

解决方法也很简单——在test函数中不关闭Scanner对象,只在main函数结尾关闭。

import java.util.Scanner;

public class TestScanner {

    public static void test() {
        Scanner b = new Scanner(System.in);
        System.out.println("(test)输入第一个数");
        int number = b.nextInt();
        System.out.println("test: " + number);
        // b.close();
    }

    public static void main(String[] args) {
        Scanner a = new Scanner(System.in);
        test();
        System.out.println("(main)输入第二个数");
        int number = a.nextInt();
        System.out.println("main: " + number);
        a.close();
    }
}

运行成功:
运行成功

总结

只在程序结尾对Scanner对象进行一次关闭!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值