以下是我输入学号的代码: 当用户以意外的格式输入数字时,我会要求他们通过递归重新输入。但它最终会产生一个不定式的递归。为什么呢?
private static int inputStudentNumber(){
System.out.println("Enter the student number:");
int studentNum;
try {
//Scanner in initialized before calling this method
studentNum = in.nextInt();
return studentNum;
} catch(Exception e) {
System.out.println("Invalid input, it can only be integer.");
return inputStudentNumber();
}
}
答案 0 :(得分:7)
仔细查看javadocs for Scanner.nextInt
:
如果下一个标记无法转换为有效的int值,则此方法将抛出
InputMismatchException
,如下所述。 如果翻译成功,扫描仪将超过匹配的输入。 (强调添加)
如果不成功,扫描仪不会进展。这意味着如果您再次尝试调用nextInt()
,那么您将尝试从获取与之前相同的令牌的int,并且您将再次获得InputMismatchException
。
您的代码基本上说:尝试将下一个标记读作int。如果失败,请尝试再次尝试将令牌读作int。如果失败,请尝试再次尝试将令牌读作int。如果失败了......(依此类推,直到你从过多的递归中得到StackOverflowException
)。
如果你想为此使用递归,你应该使用next()
跳到下一个标记。并且只抓住InputMismatchException
,这样你就不会抓住NoSuchElementException
(这对于System.in
来说不会发生,但总的来说是好的做法 - 如果你后来决定从文件中读取,那个文件已经到了结尾?)。
} catch(InputMismatchException e) {
System.out.println("Invalid input, it can only be integer.");
in.next(); // skip this token
return inputStudentNumber();
}
更好的方法是避免使用异常来控制逻辑。要做到这一点,您必须提前知道nextInt
是否会成功。幸运的是,hasNextInt()
让你做到了!
private static int inputStudentNumber() {
System.out.println("Enter the student number:");
if (in.hasNextInt()) {
return in.nextInt();
} else {
System.out.println("Invalid input, it can only be integer.");
in.next(); // consume the token
return inputStudentNumber();
}
}
这里的优势 - 除了一般"不使用控制流的例外"建议 - 基本情况是非常明确的。如果准备就绪,那就是你的基本情况;如果没有,你必须推进扫描仪,然后再试一次。
答案 1 :(得分:1)
问题是如果输入非整数作为输入,则扫描仪不会使用该输入。所以你继续阅读它。
您可能只想将输入作为字符串读取,然后尝试单独转换它。
答案 2 :(得分:0)
您的问题可能是in.nextInt()抛出异常。我看到的代码味道是你使用的:
catch(Exception e) {
....
}
这里的最佳做法是仅捕获您期望的特定异常,因此它应该是:
catch(InputMismatchException e) {
....
}
如果你这样做,那么抛出的任何in.nextInt()
将正确地传播到顶部,你可能会看到in没有被初始化或者出现这样的问题。
请参阅此处了解nextInt()
可以抛出的例外情况。
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextInt()
答案 3 :(得分:-1)
try this...
private static int inputStudentNumber(){
System.out.println("Enter the student number:");
int studentNum;
int var = 1;
while(var ==1)´
{
try{
studentNum = in.nextInt();
var=0;
return studentNum;
}catch(Exception e){
System.out.println("Invalid input, it can only be integer.");
var=1;
return inputStudentNumber();
}
}
}