最近发现了一个问题,使用Scanner输入流时,如果做了异常处理,nextInt输入有误抛出异常时,循环在次输入会出现无限循环抛出异常,直至栈溢出,程序崩掉。这是什么原因呢?
Scannersc=newScanner(System.in);
booleanflag=true;
System.out.println("请输入您需要的信息:");
while(flag){
try{
intnumber=sc.nextInt();
}catch(Exceptione){
System.out.println("您的输入有误,请重新输入");
e.printStackTrace();
}
}
通过查资料解决了这个问题,这是由于Scanner接受键盘输入信息的机制所造成的后果:
Scanner在接受键盘输入时,在内存中会有一段专门用来接收键盘输入的信息。键盘信息输入内存以后与你定义的接收输入的类型匹配,如果不匹配会抛出异常,但是键盘输入的信息会停留在内存当中,当下次需要输入时直接读取该内存存在的值,继续抛出异常,导致无限循环。这种情况的解决方法有三种:
1. 在try catch块中,异常处理时,声明一个sc.next();这一句话的作用是读取一次内存中的内容,这样等待键盘输入内存中的数据被清空,下一次可以输入
Scannersc=newScanner(System.in);
booleanflag=true;
System.out.println("请输入您需要的信息:");
while(flag){
try{
intnumber=sc.nextInt();
}catch(Exceptione){
System.out.println("您的输入有误,请重新输入");
sc.next();
e.printStackTrace();
}
} }
2. 每次使用Scanner之前,new Scanner(SyStem.in);也能解决问题,但是这样做非常的消耗性能。
while(flag){
try{
sc=newScanner(System.in);
intnumber=sc.nextInt();
break;
}catch(Exceptione){
System.out.println("您的输入有误,请重新输入");
//sc.next();
e.printStackTrace();
}
}
3. 每一个输入都使用nextLine();接收输入后,对接收的数据进行类型的强制转换。类型无法转换会抛出异常
while(flag){
try{
Stringstr=sc.nextLine();
intnumber=Integer.parseInt(str);
break;
}catch(Exceptione){
System.out.println("您的输入有误,请重新输入");
//sc.next();
e.printStackTrace();
}
}