java关于在死循环(while(true))接收用户输入不匹配异常(InputMismatchException)的几种解决方法

    技术2022-07-10  134

    前言

    我们做项目时通常需要接收用户输入的各种类型数据,比如说请用户输入年龄,那么我们就用 int age = scanner.nextInt();来接收对吧!

    public class 输入不匹配异常 { static Scanner scanner = new Scanner(System.in);//静态方法,接收用户的输入 public static void main(String[] args) { System.out.println("请输入年龄"); int age = scanner.nextInt();//用整型接收用户输入 System.out.println("用户年龄: " + age); } }

    这时,如果正常输入一个整数,那台下就是一片和谐的声音,如下

    请输入年龄 1 用户年龄: 1 Process finished with exit code 0

    可惜,并不是所有人都喜欢和谐。如果有个用户是那种搞事情派的,他偏偏输入一个小数进去,这时就会报出一个叫做“输入不匹配”的异常出来(InputMismatchException),如下的第三行 java.util.InputMismatchException

    请输入年龄 1.3 Exception in thread "main" java.util.InputMismatchException at java.base/java.util.Scanner.throwFor(Scanner.java:939) at java.base/java.util.Scanner.next(Scanner.java:1594) at java.base/java.util.Scanner.nextInt(Scanner.java:2258) at java.base/java.util.Scanner.nextInt(Scanner.java:2212) at lcy.常见问题解决方法.输入不匹配异常.main(输入不匹配异常.java:10) Process finished with exit code 1

    那有朋友就说了,有异常了tryCatch一下不就好了嘛?就像下面这样

    public static void main(String[] args) { int age = 0;//将年龄定义在 try 外面 System.out.println("请输入年龄"); try { age = scanner.nextInt();//用整型接收用户输入 } catch (InputMismatchException e) { System.out.println("输入的值不匹配"); } System.out.println("用户年龄: " + age); }

    是的,这如果输入不不是一个整数的话,他会执行 catch代码块 里面的操作,后面的用户年龄还是为0 ,这不失为一个好的解决方法,如下

    请输入年龄 1.3 输入的值不匹配 用户年龄: 0 Process finished with exit code 0

    可问题是我们要操作的是一个系统,也就是说他会一直在等待你的输入,接收到你的输入后再进行下一步操作,操作完又等待你的输入,直到你输入一个退出的标志符它才结束这个系统的运行(我在这里定义了输入 0 就退出循环)。(也就是说,他会用一个 while(true)来包裹着我们的代码块,一直接收我们的输入),那我们就进入正题。

    while(true) 里面的 InputMismatchException

    代码就是这样的

    public static void main(String[] args) { while (true) {//一直接收用户输入 int age = 0;//将年龄定义在 try 外面 System.out.println("请输入年龄"); try { age = scanner.nextInt();//用整型接收用户输入 } catch (InputMismatchException e) { System.out.println("输入的值不匹配"); continue;//跳出此次的 while 循环,执行下一次 while 循环 } //当接收到的值为 0 时就退出循环,否则就打印出接收到的值 if (age == 0) { break; } else { System.out.println("用户年龄: " + age); } } //上面是 while 循环,到这里就退出了循环 System.out.println("已退出 while 循环"); }

    正常来输入的话也可以,但是如果搞事情派来了,那么就会陷入死循环,如下

    请输入年龄 1.2 输入的值不匹配 请输入年龄 输入的值不匹配 请输入年龄 输入的值不匹配 ... ... ... Process finished with exit code -1

    这是因为输入类型错误了,虽然他抓到异常,并执行本异常的 catch块 里面的代码,但是 scanner 接收输入的值因为传不出去,所以还存在于 scanner 里面,也就是说这个 scanner 还是你刚刚输入的值。

    小结:由上面所说的可知,这个值又进去下一次循环里面继续赋值,所以还是传不出去,就进入了死循环。

    解决方法

    我目前想出了两个好用的解决方法。

    1.转换数据类型法
    思路: 1. 用一个通用的 String 作为中转值,来接收输入的值 2. 定义全部匹配数字的正则表达式 3. 尝试着将这个 String 转换为纯数字 4. 定义标志位来判断转换成功或者失败 5. 转换成功就赋值给我们现在想要的 int 类型 6. 不成功就提示一下,退出本次 while 循环,执行下一次 while 循环

    我们要将 tryCatch 里面的代码改成以下代码

    String temp = scanner.nextLine();//中转值 boolean flag = temp.matches("[0-9]+");//正则,全部匹配数字 /** 本正则解析 * [0-9]: 每一次个字符都只匹配这些数字 * +: 无限次匹配 */ if (flag) {//如果匹配成功,也就是输入的字符串里面全是数字 age = Integer.parseInt(temp);//将 temp 转换为 int 类型,并传递给我们想要的 age } else {//如果匹配不成功就进入下一次循环 System.out.println("输入的值不匹配"); continue;//跳出此次的 while 循环,执行下一次 while 循环 }

    看一下执行的结果

    请输入年龄 6.5 输入的值不匹配 请输入年龄 6.4 输入的值不匹配 请输入年龄
    2.重新接收输入法

    这个就很简单了,同样用思路来表达

    1. 让 scanner 再接收一下数据来覆盖掉原来的数据,这时再退出本次 while 循环 2. 进入下一次循环时就将新数据传给我们想要的 int ,如果还是不成功就在 catch 块里面执行思路1,又执行思路2……

    这次就是在 catch 块里加了一行代码,catch 块如下

    catch (InputMismatchException e) { System.out.println("输入的值不匹配"); scanner.next();//接收下一次输入,下次循环中就给想要的 int 传递这个接收到的值 continue;//跳出此次的 while 循环,执行下一次 while 循环 }

    看下结果

    请输入年龄 4.5 输入的值不匹配 请输入年龄 6.7 输入的值不匹配 请输入年龄

    总结

    两个方法执行的效果一样,都解决了在 while(true)中出现的输入不匹配异常(InputMismatchException)。但是无论从思路理解方面,还是从代码读取方面,亦或是执行效率方面,都是方法二更胜一筹。

    后言

    一个新手分享经验,凭本心说,写的不好。感谢您耐心的观看,您的收获与您的支持是我的最大动力。

    再次衷心感谢!!

    Processed: 0.010, SQL: 9