为什么我只收到类型错误而不是零除错误?

3
所以,我有两个问题。第一个是,在Java中,我该如何做与这个Python代码等效的操作:
while True:
    try:
        num1 = int(input('Enter num1: '))
        num2 = int(input('Enter num2: '))
        print(str(num1) + ' / ' + str(num2) + ' = ' + str(num1 / num2))
        break

    except:
        print('ERROR')

我希望程序能够对用户说:“不,你做错了!现在再做一遍直到做对为止。”我尝试用Java编写了以下代码:

import java.util.Scanner;

public class TryCatch {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        while (true) {
            try {
                System.out.print("Enter num1: ");
                int num1 = input.nextInt();
                System.out.print("Enter num2: ");
                int num2 = input.nextInt();
                System.out.println(num1 + " / " + num2 + " = " + num1 / num2);
                break;
            } catch (Exception e) {
                System.out.println(e);
                System.out.println(e.getCause());
                System.out.println(e.getMessage());
            }
        }
    }
}

现在当num2等于0时,它会完全按照我的要求执行。以下是当发生这种情况并且我在第一次迭代后终止进程时的输出结果:

Enter num1: 5
Enter num2: 0
java.lang.ArithmeticException: / by zero
null
/ by zero
Enter num1: 
Process finished with exit code 1

然而,当num1或num2为字符串时,java会打印以下三行并进入无限循环,直到我终止该进程:

java.util.InputMismatchException
null
null

显然,这意味着我在做错了什么,但是就我而言,我不知道为什么catch块会因为类型错误而无限循环运行,而不是除以零错误... 所以我的两个具体问题是:
  1. 如何实现我想要做的事情?即使程序告诉用户“不,你做错了!现在再做一次,直到做对为止。”
  2. 这个解决方案为什么不正确?即为什么当出现类型错误时catch块会无限循环运行,而不是除以零错误?

编辑: 由于我只能接受1个答案,所以我想特别感谢@rgettman解释nextInt()方法如何导致我的特定问题,以及@Alireza Dastyar给出了我认为更优雅的解决方案,因为它改变了抛出异常的位置,而不是在事后清理混乱的输入,这意味着当特定的异常没有被抛出时,您必须提供虚拟输入。


nextInt() 抛出 InputMismatchException 异常时,输入中没有任何字符被消耗,因此再次调用它将再次失败。您需要调用 next()nextLine() 来消耗错误的输入。 - Andreas
1个回答

1
执行永远不会到达除以零的部分。当您输入nextInt()无法处理的内容时,该方法会在执行到达除法表达式之前抛出InputMismatchException
此外,当消耗输入的Scanner方法抛出异常时,它不会消耗有问题的输入,循环重复,nextInt()相同的输入上抛出异常,导致无限循环。 nextInt() javadocs:

如果下一个标记无法像下面描述的那样转换为有效的int值,则此方法将引发InputMismatchException。如果翻译成功,则扫描器将超过匹配的输入。

  1. catch块中,向用户打印消息以再次尝试。
  2. catch块中调用input.next()以消耗不正确的输入并前进到下一个标记。
当第一个输入是不正确的时候,您需要仔细处理输入;在这种情况下,可能需要跳过2个输入标记。
考虑调用hasNextInt()来确定是否有整数要解析。

非常感谢!我对Python很熟悉,所以Scanner类的怪癖对我来说都很不直观。 你知道nextInt()方法为什么会这样吗?我想不出有什么情况下会用到这个。 - mrsuperguy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接