Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 递归导致的无限循环(介绍性)_Java_Recursion_Infinite Loop - Fatal编程技术网

Java 递归导致的无限循环(介绍性)

Java 递归导致的无限循环(介绍性),java,recursion,infinite-loop,Java,Recursion,Infinite Loop,我试图写一个方法,使人们能够通过扫描器输入整数,而不会因为异常而导致程序崩溃。这是我最初拥有的:(这里,sc是一个Scanner对象) 当我用无效输入测试程序时,启动了一个无限循环,在Eclipse停止之前,多次打印消息和“必须输入一个整数”。 我使用以下代码修复了此问题: public static int inputInt(String message) { int returnval = 0; System.out.println(message); Strin

我试图写一个方法,使人们能够通过扫描器输入整数,而不会因为异常而导致程序崩溃。这是我最初拥有的:(这里,sc是一个Scanner对象)

当我用无效输入测试程序时,启动了一个无限循环,在Eclipse停止之前,多次打印消息和“必须输入一个整数”。 我使用以下代码修复了此问题:

 public static int inputInt(String message) { 
    int returnval = 0;
    System.out.println(message);
    String valstring = sc.nextLine();
    try {
        returnval = Integer.parseInt(valstring);
    } catch (Exception ex) {
        System.out.println("You must enter an integer.");
        inputInt(message);
    }
    return returnval;
}

为什么第一种方法失败了,而第二种方法没有失败?是否有更干净的方法来实现这一点?

是的,有更干净的方法:使用
hasnetint

public static int inputInt(String message) {
    System.out.println(message);
    while (!sc.hasNextInt()) {
        sc.nextLine(); // clear the bad input first

        System.out.println("You must enter an integer.");
        System.out.println(message); // why use recursion? just use a while loop
    }
    return sc.nextInt();
}
我所做的改变是:

  • 使用
    hasNextInt
    ,因此不必使用异常
  • 添加了
    sc.nextLine()(问题的根源)
  • 而不是递归,只是做一个while循环(当你可以简单循环时为什么要递归?)
  • 消除临时变量
  • 使其更具可读性(IMO)

是的,有一种更干净的方法:使用hasNextInt

public static int inputInt(String message) {
    System.out.println(message);
    while (!sc.hasNextInt()) {
        sc.nextLine(); // clear the bad input first

        System.out.println("You must enter an integer.");
        System.out.println(message); // why use recursion? just use a while loop
    }
    return sc.nextInt();
}
我所做的改变是:

  • 使用
    hasNextInt
    ,因此不必使用异常
  • 添加了
    sc.nextLine()(问题的根源)
  • 而不是递归,只是做一个while循环(当你可以简单循环时为什么要递归?)
  • 消除临时变量
  • 使其更具可读性(IMO)

是的,有一种更干净的方法:使用hasNextInt

public static int inputInt(String message) {
    System.out.println(message);
    while (!sc.hasNextInt()) {
        sc.nextLine(); // clear the bad input first

        System.out.println("You must enter an integer.");
        System.out.println(message); // why use recursion? just use a while loop
    }
    return sc.nextInt();
}
我所做的改变是:

  • 使用
    hasNextInt
    ,因此不必使用异常
  • 添加了
    sc.nextLine()(问题的根源)
  • 而不是递归,只是做一个while循环(当你可以简单循环时为什么要递归?)
  • 消除临时变量
  • 使其更具可读性(IMO)

是的,有一种更干净的方法:使用hasNextInt

public static int inputInt(String message) {
    System.out.println(message);
    while (!sc.hasNextInt()) {
        sc.nextLine(); // clear the bad input first

        System.out.println("You must enter an integer.");
        System.out.println(message); // why use recursion? just use a while loop
    }
    return sc.nextInt();
}
我所做的改变是:

  • 使用
    hasNextInt
    ,因此不必使用异常
  • 添加了
    sc.nextLine()(问题的根源)
  • 而不是递归,只是做一个while循环(当你可以简单循环时为什么要递归?)
  • 消除临时变量
  • 使其更具可读性(IMO)
问题
Scanner.nextInt()
具有引发3个异常的能力:

1-
inputmaschException
:当下一项不是
int
时抛出
2-
NoTouchElementException
:当没有下一个事件时
3-
非法状态异常
:如果
扫描仪
已关闭

因此,当您输入非法值(例如“abc”)时,最上面的代码会执行以下操作:

接受“abc”并尝试将其转换为int.(
nextInt()
)。因为“abc”不是一个数字,所以它不能转换,并抛出一个
输入不匹配异常
。然而,由于该方法没有成功完成,“abc”被保留为下一个要读取的项目。由于引发了异常,因此
catch
块中的代码将运行。它打印出“您必须输入一个整数”,然后再次调用自己,传递自己的
消息
。然后它初始化
returnval
,并打印出第一次运行时的相同
消息
,因为您再次将其传递给自己。然后进入
try
块,由于“abc”没有成功读取并留在那里,扫描仪读取“abc”并再次尝试将其转换为
int
。当然,这行不通,循环又开始了

解决方案 现在你知道你的问题是什么了,你可以想出一个解决办法。在我看来,最优雅的方法是使用
Scanner
方法,
hasnetint()
。这将返回一个
boolean
,让您知道下一个要读取的项目是否可以转换为
int
。例如,如果下一项是“abc”,则该方法将返回
false
。对于下一项“1”,该方法将返回
true
。因此,如果您这样修改代码,它应该可以工作:

public static int inputInt(String message) {                                            
    int returnval = 0;
    System.out.println(message);
    while(!sc.hasNextInt()) {
        sc.nextLine();
        System.out.println("You must enter an integer.");
    }
    returnval = sc.nextInt();
    return returnval;
}
此代码的作用是:

1-初始化
returnval
并打印
消息

2-只要扫描仪没有要读取的
int
,就进入while循环。有效地“等待”下一个
int
输入
3-一旦有一个
int
要读取,它就会读取int并将值保存在
returnval

4-它向调用者返回
returnval

(慢条斯理赢得了比赛,哈哈。我似乎总是反应迟钝。也许是因为我写了一些小小说作为答案……)

问题
Scanner.nextInt()
具有引发3个异常的能力:

1-
inputmaschException
:当下一项不是
int
时抛出
2-
NoTouchElementException
:当没有下一个事件时
3-
非法状态异常
:如果
扫描仪
已关闭

因此,当您输入非法值(例如“abc”)时,最上面的代码会执行以下操作:

接受“abc”并尝试将其转换为int.(
nextInt()
)。因为“abc”不是一个数字,所以它不能转换,并抛出一个
输入不匹配异常
。然而,由于该方法没有成功完成,“abc”被保留为下一个要读取的项目。由于引发了异常,因此
catch
块中的代码将运行。它打印出“您必须输入一个整数”,然后再次调用自己,传递自己的
消息
。然后它初始化
returnval
,并打印出第一次运行时的相同
消息
,因为您再次将其传递给自己。然后进入
try
块,由于“abc”没有成功读取并留在那里,扫描仪读取“abc”并再次尝试将其转换为
int
。当然,这行不通,循环又开始了