首页 > 解决方案 > 有谁知道在使用递归调用时无限循环和 StackOverflow 错误发生了什么?

问题描述

这是我为练习而制作的程序的一部分,它的目的并不重要。
我已经将 Scanner 声明为类的一个字段**(抱歉,这里没有写)。
我想创建一个方法来返回指定给用户输入的答案。而且我想做所有需要的检查,这样用户就不能输入字符或符号,只能输入一个整数。当输入数据的类型错误时,我希望用户再次尝试输入。

public static void Answer() {

System.out.println("\n\t1.It was good! \n\t2.Kinda bad too...");
System.out.println();

if (scanner.hasNextInt()) {

  int choice = scanner.nextInt();

  switch (choice) {
  case 1:
    System.out.println("Oh great!");
    break;
  case 2:
    System.out.println("I see you as well");
    break;
  default:
    System.out.println("Please select a valid answer :");
    Answer();
    break;
  } else {

    System.out.println("Please select a number, characters are not acceptable!");

    Answer();

  }

当我输入 3,4 等无效数字时,算法也会触发 switch 块和递归调用,工作得很好!
但是当我输入一个字符时,它会触发一个无限递归调用,而不会让我从扫描仪输入新的输入并最终导致StackOverflow错误。

标签: javarecursionjava.util.scannerstack-overflow

解决方案


您检查扫描仪是否有int. 如果没有,则转到else分支。

else分支中,它Answer()再次调用。但这里有一个问题:您的扫描仪仍然没有int. 所以scanner.hasNextInt()返回falsehasNextInt()不会尝试读取任何内容 - 它只是检查是否有可以解释为int. (来源:Java 文档)。

所以程序再次转到else分支,没有到达它可以尝试读取输入的点......然后它Answer()再次调用。现在,代码仍然没有int... 所以再次scanner.hasNextInt()返回 false,然后转到else分支。再一次,它没有到达扫描仪消耗输入的部分,而是到达它Answer()再次调用的部分......

这将继续,直到调用堆栈已满并且您收到 StackOverflow 错误。

您必须注意用户输入的内容不是int. 您将不得不使用不是int.

顺便说一句,我更喜欢使用迭代而不是递归来做到这一点。


推荐阅读