Fan*_*Fan 2 java recursion exception 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();
}
}
Run Code Online (Sandbox Code Playgroud)
InputMismatchException如果下一个标记无法转换为有效的int值,则抛出此方法,如下所述.如果翻译成功,扫描仪将超过匹配的输入.(重点补充)
如果不成功,则扫描仪不会前进.这意味着如果你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();
}
Run Code Online (Sandbox Code Playgroud)
更好的方法是避免使用异常来控制逻辑.要做到这一点,你必须提前知道是否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();
}
}
Run Code Online (Sandbox Code Playgroud)
这里的优势 - 除了一般的"不使用控制流程的例外"建议 - 基本情况是非常清楚的.如果有一个int准备就绪,这是你的基本情况; 如果没有,你必须推进扫描仪,然后再试一次.