try-catch为零除

Fir*_*rat 14 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");

    }
}
Run Code Online (Sandbox Code Playgroud)

ken*_*ytm 23

除以零对浮点数有效.

  • 1/0产生无穷大.
  • (-1)/ 0产生-Infinity.
  • 0/0产生NaN.

这些"数字"在IEEE 754中正确定义.

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


Boz*_*zho 14

我建议验证:

if (divisor != 0) {
    // calculate
}
Run Code Online (Sandbox Code Playgroud)

而不是捕捉异常


Ste*_*n C 8

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

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

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

  • 除了前面的项目,这是一个坏主意赶上Exception,RuntimeException,ThrowableError.这样做会捕获大量您可能不想捕获的异常.在这种情况下,因为你期待一个ArithmeticException,你应该抓住那个.

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

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

EDIT详细阐述了回应@Jay评论的第一点.

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

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

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