捕获异常时的不定式递归

时间:2015-01-27 22:36:55

标签: java exception recursion java.util.scanner

以下是我输入学号的代码: 当用户以意外的格式输入数字时,我会要求他们通过递归重新输入。但它最终会产生一个不定式的递归。为什么呢?

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

4 个答案:

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


}