try-catch为零除

时间:2010-02-13 21:50:55

标签: java try-catch divide-by-zero

我的问题是关于try-catch块的简单除法示例。你看到第一行尝试?如果我将这两个变量中的任何一个转换为double,则程序无法识别catch块。在我看来,我是否必须执行捕获块。这段代码出了什么问题?

public static void main(String[] args) {

    int pay=8,payda=0;  

    try {

        double result=pay/(double)payda; // if I cast any of the two variables, program does not recognize the catch block, why is it so?
        System.out.println(result);
        System.out.println("inside-try");

    } catch (Exception e) {

        System.out.println("division by zero exception");
        System.out.println("inside-catch");

    }
}

7 个答案:

答案 0 :(得分:23)

除以零对浮点数有效。

  • 1/0产生无限。
  • ( - 1)/ 0产生-Infinity。
  • 0/0产生NaN。

这些“数字”在IEEE 754中正确定义。

另一方面,整数除以零,因为一个不能将无穷大表示为int

答案 1 :(得分:14)

我建议验证:

if (divisor != 0) {
    // calculate
}

而不是捕捉异常

答案 2 :(得分:8)

由于你是一位自称为“新手”的人,我认为用你的代码指出一些更广泛的问题是个好主意。 (我知道这不是生产代码,但只是为了论证而假设它是。)

  • 如果出现异常,如果检测到引起异常的情况,通常会更简单,更清晰,更有效。在这种情况下,如果您希望divisor偶尔为零,最好在进行除法之前对其进行测试。

  • 另一方面,如果异常完全出乎意料(即“bug”),最好的策略是让异常传播到最外层。此时,您的应用程序catch应捕获所有异常,记录异常堆栈跟踪并保释。

  • 除了上一个项目符号外,抓住ExceptionRuntimeExceptionThrowableError是个坏主意。这样做会捕获大量您可能不想捕获的异常。在这种情况下,由于您期望ArithmeticException,因此您应该抓住这一点。

  • 在财务应用程序中使用floatdouble很少是正确的。这些类型并不精确,但财务应用程序通常需要精确处理大量资金。

  • 更一般地说,浮点数对于非专业人士(和新手)来说很难理解。人们期望持有的许多“真理”实际上并不成立。例如,1.0/3.0 + 1.0/3.0 + 1.0/3.0的浮点计算不会给1.0。类似地(如您所发现的),除零行为表现不同。如果你想安全地使用浮点,你需要了解陷阱。

编辑详细阐述了回应@Jay评论的第一点。

首先,我故意使用“通常”这个词。有些情况下,避免抛出预期的异常就无法实现。

话虽如此,即使你的应用程序无法立即处理这种情况,你也经常不希望发生通用的“预期”异常。例如,如果OP的代码是更大的代码的一部分,那么显式抛出IllegalArgumentException(如果这是违反API契约)或者如果我们知道这是UserEnteredRubbishException则可能更好。用户输入错误的结果(并且有机会报告/纠正它)。

我们“期待”异常的事实意味着根据定义我们对它的了解比(比如)通用ArithmeticException所说的更多。如果我们允许传播通用异常,则会使catch块更难以使许多堆栈帧正常运行。例如,在这种情况下,远程捕获块无法以任何确定性来诊断被零除的原因。 ArithmeticException 可能来自应用程序的不同部分,可能甚至可能是零除!解决方法是明确抛出更具体的异常。

答案 3 :(得分:3)

答案在于程序自己的输出 - 它为result打印“无限”。这是因为Java只允许整数除零 - 浮点除零是合法的并产生Infinity

请参阅DoubleFloat的文档,了解POSITIVE_INFINITYNEGATIVE_INFINITY常量。

答案 4 :(得分:2)

只有用整数除零才会引发ArithmeticException。 使用double或float除以零将导致 Infinity

答案 5 :(得分:1)

因为除以两个双打返回无穷大,但不抛出。您可以使用isInfinite()进行检查。但是,适当的解决方案(如前所述)是在划分前检查分母。

答案 6 :(得分:0)

没有人会试图让RuntimeException从代码中抛出。可以(并且应该)轻松避免这些Exception