呵呵,楼主这是一个很经典的问题。
【效果图】
如果调用input(3)
结果如下:
1>5
2>2.1
只能输入整数!
2>2
3>1
【正确的源代码】
import java.util.InputMismatchException;
import java.util.Scanner;
public class hi
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
input(3);
}
public static int[] input(int length)
{
Scanner scanner = new Scanner(System.in);
int[] array = new int[length];
int in = 0;
for (int i = 0; i < length; i++)
{
System.out.print((i + 1) + ">");
try
{
in = scanner.nextInt();
}
catch (InputMismatchException e)
{
i--;
System.out.println("只能输入整数!");
//上次输错的那个数据还在缓冲流中。定义一个字符串变量把它读走就完了。
String clear=scanner.next();
continue;
}
array[i] = in;
}
return array;
}
}
【解释】
1、你的死循环
每次catch发现错误后。i--确实没有问题,从截图可以看出你的i确实没有动。
但是还是继续提示”数据不是合法整数“。这是上一次输入错误的那个还留在输入管道中没有取走。所以会一致死循环错下去。应为你的i原定不动了。
2、解决办法
catch里,我们定义一个Sting类型的变量,把输入错误的那个数读出来。考虑输入的都可以看成字符串,所以就用String类型了。
晚安!
首先解释下 input 方法为什么死循环问题
问题描述
Scanner scanner = new Scanner(System.in);
scanner 对象使用到 nextInt()方法时,是必须输入整数型数字,非整数型字符在键入回车的一瞬间,马上抛出异常信息,此异常是nextInt()方法封装的异常信息.
在此时楼主使用到 try catch 对异常代码进行异常处理,并且 使其for循环中的i 变量-- ,并使用 continue;所以 此时i变量的值又回到上一次正确执行for循环主体时i的值. 那么此时for循环会每次执行.
问题分析:
在for循环的影响下
Scanner 的nextInt 方法,为了节约系统内存,程序会读取上一次的全部输入,包括回车符, 如果上一次的输入中不满足nextInt方法的要求,马上抛出异常,那么此时键盘输入并没有清空,所以下一次调用nextInt方法时,还是直接读取上一次非数字字符,一直抛出异常,周而复始.
如果上一次键盘是正常输入,nextInt方法会自动清空缓存,当前的状态为键盘输入,目的是节约系统内存.
下面为jdk 的源代码
public int nextInt(int radix) {
// Check cached result
if ((typeCache != null) && (typeCache instanceof Integer)
&& this.radix == radix) {
int val = ((Integer)typeCache).intValue();
useTypeCache();
return val;
}
setRadix(radix);
clearCaches();
// Search for next int
try {
String s = next(integerPattern());
if (matcher.group(SIMPLE_GROUP_INDEX) == null)
s = processIntegerToken(s);
return Integer.parseInt(s, radix);
} catch (NumberFormatException nfe) {
position = matcher.start(); // don't skip bad token
throw new InputMismatchException(nfe.getMessage());
}
}
解决代码:
并指出楼主在程序的缺陷:
1.一般情况下尽量不要去改变for循环中i的变量值.
2.如果非情况的下的循环,尽量使用 do while 这种循环.
贴出优化的代码
public static int[] input(int length){
Scanner scanner = new Scanner(System.in);
int[] array = new int[length];
int in = 0 ;
for (int i = 0; i < length; i++) {
do{
try{
System.out.print((i+1)+">");
in = Integer.parseInt(scanner.nextLine());
}catch (NumberFormatException e) {
System.out.println("只能输入整数!");
continue;
}
break;
}while(true);
array[i]= in ;
}
return array;
}
InputMismatch这个异常就是错一次后以后的都认为的异常的。所以可以得话尽量不用scanner去转型,自己做类型转换。
Scanner scanner = new Scanner(System.in);
int[] array = new int[10];
String s;
int in = 0 ;
for (int i = 0; i < 10; i++) {
System.out.print((i+1)+">");
try{
s=scanner.nextLine();
in = Integer.parseInt(s);
}catch (NumberFormatException e) {
System.out.println("只能输入整数!");
i--;
continue;
}
array[i]=in;
}
public static int[] input(int length){
Scanner scanner = new Scanner(System.in);
int[] array = new int[length];
int in = 0 ;
boolean flag = true;
for (int i = 0; i < length; i++) {
System.out.print((i+1)+">");
do{
try{
in = scanner.nextInt();
}catch (InputMismatchException e) {
System.out.println("只能输入整数!");
flag = true;
continue;
}
flag = false;
}while(flag);
array[i]=in;
}
return array;
}
i-- 换成i++