捕获异常时不定式递归
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
,这样你就不会同时捕获 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();
}
}
除了一般的 "don't use exceptions for control flow" 建议之外,这里的优点是基本情况非常清楚。如果有一个 int 准备好了,那就是你的基本情况;如果不是,则必须推进扫描仪并重试。
问题在于,如果输入的是非整数,则扫描仪不会使用该输入。所以你就继续读吧。
您可能只想将输入读取为字符串,然后尝试单独转换它。
这是我输入学号的代码: 当用户以意想不到的格式输入数字时,我会要求他们通过递归重新输入。但它以不定式递归结束。为什么?
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
,这样你就不会同时捕获 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();
}
}
除了一般的 "don't use exceptions for control flow" 建议之外,这里的优点是基本情况非常清楚。如果有一个 int 准备好了,那就是你的基本情况;如果不是,则必须推进扫描仪并重试。
问题在于,如果输入的是非整数,则扫描仪不会使用该输入。所以你就继续读吧。
您可能只想将输入读取为字符串,然后尝试单独转换它。