Java Scanner.nextxxx() 相关的异常处理

本文详细讲述了在Java中处理Scanner输入异常时,InputMismatchException的含义,以及在捕获异常后Scanner内存的行为。重点讲解了如何避免因内存缓存导致的无限循环问题,并给出了修复建议。
摘要由CSDN通过智能技术生成

所遇到的情况如下

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    int i;
    try {
        System.out.println("请输入一个整数值");
        i = input.nextInt();
        System.out.println("i:" + i);
    } catch (InputMismatchException e) {
        e.printStackTrace();
        System.out.println("输入格式不匹配");
    }
}

上述代码新建一个input引用变量,并将之引用Scanner,try模块中,通过input.nextInt() 获得一个整数值。
对于try模块中,若用户正常通过控制台输入一些整数,那程序将正常运行。但是若用户通过控制台输入了一些非全部为整数的东西,比如sfs1321,那么catch模块将会捕捉到一个InputMismatchException的异常,意思就是说输入的格式与期望的不匹配。

那么,在捕获到InputMismatchException的异常后,Scanner内存保存什么呢?看下述代码:

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    int i;
    try {
        System.out.println("请输入一个整数值");
        i = input.nextInt();
        System.out.println("i:" + i);
    } catch (InputMismatchException e) {
        e.printStackTrace();
        System.out.println("输入格式不匹配");
    } finally {
        System.out.println(input.next());
    }
}

在上述代码中,我在catch后面加了一个finally模块,并在内部通过input.next()输出Scanner内存缓存的东西。
运行效果如下;
在这里插入图片描述
可见,当catch模块捕获到Scanner的输入的InputMismatchException异常后,上一次输入的数据将暂存在Scanner的内存缓存区。

一些小东西:验证格式输入的循环代码

有问题的原代码:

Scanner input = new Scanner(System.in);
int id = 0;
while (true) {
    try {
        System.out.println("请输入ID");
        id = input.nextInt();
        System.out.println("id:" + id);
        break;
    } catch (InputMismatchException e) {
        e.printStackTrace();
        System.out.println("输入格式不匹配");
    }
}

当正常输入整数时,程序正常运行。
当输入不全为整数时,代码将无限循环下去,且从第二次循环开始,每次均跳过try模块。

出现此问题的原因如下:
结合 所遇到的情况 章节中所介绍的东西。Scanner在接收任意输入后,会暂时将数据保存至内存缓存区,然后再通过内存缓存区传给所需要的nextxxx()函数。
在输入一个不全为整数的数据时,由于此数据格式与input.nextInt()所要求的整数格式不同,所以并不会将内存缓存区的数据传给nextInt(), 同时catch捕获到InputMismatchException异常,将执行catch模块的代码。在第二次循环时,由于Scanner的内存缓存区依旧存有数据,故直接将内存缓存区的数据传给nextInt(),然后又抛出InputMismatchException的异常,故而无限无限循环循环下去。

解决办法:
改动代码如下:

public static void main(String[] args) {
   Scanner input = new Scanner(System.in);
   int id = 0;
   while (true) {
       try {
           System.out.println("请输入ID");
           id = input.nextInt();
           System.out.println("id:" + id);
           break;
       } catch (InputMismatchException e) {
           e.printStackTrace();
           input.next();
           System.out.println("输入格式不匹配");
       }
   }
}

注:

nextInt() next() nextFloat()等方法,在获取Scanner的内存缓存区的数据后,光标将停留在当前行的末尾,并没有将’\n’传给方法。

nextLine()不同于上面的方法,在获取Scanner的内存缓存区的数据后,光标将停留在新行的头部,将上一行的’\n’也传给方法了。

建议:

在进行使用Scanner进行输入时,若前后两次使用不同的方法,比如第一次使用input.nextInt(), 然后第二次使用input.nextFloat()时,建议在两次中间添加input.nextLine()以清空Scanner的内存缓存区。

小白理解,若有误,欢迎探讨。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值