try-catch为零除

我的问题是关于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"); } } 

除以零对浮点数有效。

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

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

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

我建议validation:

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

而不是捕捉exception

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

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

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

  • 除了前一个子弹,捕获ExceptionRuntimeExceptionThrowableError是一个坏主意。 这样做会捕获大量您可能不想捕获的exception。 在这种情况下,由于您期望ArithmeticException ,您应该抓住它。

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

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

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

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

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

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

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

有关POSITIVE_INFINITYNEGATIVE_INFINITY常量,请参阅Double和Float的文档。

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

因为除以两个双精度返回无穷大,但不投掷。 您可以使用isInfinite()来检查这一点。 但是,适当的解决方案(如前所述)是在划分前检查分母。

没有人应该尝试从他们的代码中抛出RuntimeException 。 可以(并且应该)轻松避免这些Exception