问题描述
Java使用在编写获取用户正确输入的逻辑代码时,采用循环读取来正确获取,其中使用try/catch语句捕捉InputMismatchException,当用户出现错误输入时,程序进入死循环,不再阻塞等待用户输入。
相关代码如下
Scanner ipt = new Scanner(System.in);
boolean input_Right = false;
do{
try{
System.out.println("Please enter an Integer:");
int integer_1 = ipt.nextInt();
System.out.println("Please enter next Integer:");
int integer_2 = ipt.nextInt();
input_Right = true;
}catch(Exception e){
System.out.println("Wrong format.");
}
}while(!input_Right);
程序输入正常的整数,运行正常。
程序输入错误的数,比如浮点数,一直输出Wrong format.和Please enter an Integer
问题剖析
出现这个问题,我们可以从输出入手。一直输出这两个字符串,说明进入了catch同时也运行了System.out.println(“Please enter an Integer:”);。这里能够初步判断是输入缓冲区没有处理或者忽略错误的输入,导致第一个*nextInt()*一直获取错误的输入,从而被catch,input_Right无法变为true,进而形成死循环。
java8帮助手册中也有相关的描述。Scanner类中的偏上面的部分
When a scanner throws an InputMismatchException, the scanner will not
pass the token that caused the exception, so that it may be retrieved
or skipped via some other method.
这也就解释了,为什么如果不进行retrieve(重新获取)或者skipped(忽略,跳过)的话错误的输入会一直存在,从而死循环。
解决方法
弄清楚原因后,自然能够解决了。
方法1:重新获取
重新获取,但是仅仅是把数据从缓冲区取出来。并不对数据进行处理。使用Scanner的next()方法就能够解决。
具体如下
Scanner ipt = new Scanner(System.in);
do{
try{
... ...
}catch(Exception e){
ipt.next();
System.out.println("Wrong format.");
}
}while(!input_Right);
方法2:清空缓冲区(推荐方法)
将上一个Scanner关闭,新建一个Scanner实例
帮助手册中
When a Scanner is closed, it will close its input source if the source implements the Closeable interface.
也就是说,一个Scanner关闭后,他的输入源将会关闭,里面的数据将会清空。
具体如下:
Scanner ipt = new Scanner(System.in);
do{
try{
... ...
}catch(Exception e){
ipt = new Scanner(System.in);
System.out.println("Wrong format.");
}
}while(!input_Right);