捕获异常时不定式递归

Infinitive recursion when catching an Exception

这是我输入学号的代码: 当用户以意想不到的格式输入数字时,我会要求他们通过递归重新输入。但它以不定式递归结束。为什么?

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();
    }
}

您的问题可能是 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()

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();
    }
}


}

仔细看看 javadocs for Scanner.nextInt:

This method will throw InputMismatchException if the next token cannot be translated into a valid int value as described below. If the translation is successful, the scanner advances past the input that matched. (emphasis added)

如果不成功,则扫描仪不先进。这意味着,如果您尝试再次调用 nextInt(),您将尝试从 与以前相同的标记 获取一个 int,并且您将再次获取一个 InputMismatchException.

您的代码基本上是这样说的:尝试将下一个标记读取为 int。如果失败,递归尝试再次将令牌读取为 int。如果失败,递归尝试再次将令牌读取为 int。如果失败......(依此类推,直到你从太多递归中得到 WhosebugException)。

如果你想为此使用递归,你可能应该使用 next() 跳到下一个标记。并且只捕获 InputMismatchException,这样你就不会同时捕获 NoSuchElementExceptionSystem.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();
  }
}

除了一般的 "don't use exceptions for control flow" 建议之外,这里的优点是基本情况非​​常清楚。如果有一个 int 准备好了,那就是你的基本情况;如果不是,则必须推进扫描仪并重试。

问题在于,如果输入的是非整数,则扫描仪不会使用该输入。所以你就继续读吧。

您可能只想将输入读取为字符串,然后尝试单独转换它。