如何在以下方法中修复堆栈溢出



我正在尝试编程一个处理用户输入的方法。该方法需要从控制台扫描一个int,检查扫描的int是否在Range中,然后在另一个方法中扫描另一个int之前检查数据的有效性。我决定递归地编程这个方法,如果不满足上述条件,它会调用自己来重复。

public static void readUserInputDay(Scanner scanner) {
System.out.print("Day (1-31): ");
try {
int tmp = scanner.nextInt();
day = new Integer(tmp);

if(isTheInputInRange(day.intValue(), DAY)) {
readUserInputMonth(scanner);
} else {
System.out.print("Number isn't in Range (1-31)n");
readUserInputDay(scanner);
}

} catch (Exception e) {
System.out.print("Please enter a number!n");
readUserInputDay(scanner);
}
}

其他过滤器按预期工作,但是,如果我在控制台上输入一些不是int的东西,就会触发并捕获Exception(如预期(,但当我期望Method递归地重复它自己时,我会在控制台上得到以下输出:

Day (1-31): Please enter a number!
Day (1-31): Please enter a number!
Day (1-31): Please enter a number!
Exception in thread "main" java.lang.StackOverflowError
at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)
at sun.nio.cs.UTF_8.access$200(UTF_8.java:57)
at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:636)
at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)
at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.PrintStream.write(PrintStream.java:526)
at java.io.PrintStream.print(PrintStream.java:669)
at MyClass.readUserInputDay(MyClass.java:27)
at MyClass.readUserInputDay(MyClass.java:43)
at MyClass.readUserInputDay(MyClass.java:43)

你知道我需要如何修复代码吗?这样当方法调用自己时,它就不会立即进入catch块?

提前感谢

您将在方法本身内部调用该方法3次,并根据它引起的条件在overflow error结束时重新调用它self。为了防止这个问题,首先尝试更改代码的结构,并使用while循环,例如在您想要的特定条件下继续您的代码,并获得结果:

public static void readUserInputDay(Scanner scanner) {
try {
boolean isFinished = false;
// your condition for loop
while (!isFinished) {
System.out.print("Day (1-31): ");
int tmp = scanner.nextInt();
day = new Integer(tmp);
if (isTheInputInRange(day.intValue(), DAY)) {
readUserInputMonth(scanner);
isFinished = true;
} else {
System.out.print("Number isn't in Range (1-31)n");
}
}
} catch (Exception e) {
System.out.print("Please enter a number!n");
readUserInputDay(scanner);
}
}

奇怪的是,您说StackOverflow错误发生在第一次重试时,尤其是在第一次System.out.print调用中。

然而,正如Mustafa所建议的,在这种情况下,使用while循环而不是递归是更好的选择,因为它不会导致每次有人输入错误的文本时都会创建新的堆栈帧(因为我不认为Java可以对该方法进行尾调用优化(。

public static void readUserInputDay(Scanner scanner) {
while (true) {
System.out.print("Day (1-31): ");
try {
int tmp = scanner.nextInt();
day = new Integer(tmp);

if (isTheInputInRange(day.intValue(), DAY)) {
readUserInputMonth(scanner);
break; // exit the retry loop
} else {
System.out.print("Number isn't in Range (1-31)n");
}

} catch (Exception e) {
System.out.print("Please enter a number!n");
}
// By this point, the input is invalid, so loop again
}
}

最新更新