我的问题是关于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");
}
}
答案 0 :(得分:23)
除以零对浮点数有效。
这些“数字”在IEEE 754中正确定义。
另一方面,整数除以零,因为一个不能将无穷大表示为int
。
答案 1 :(得分:14)
我建议验证:
if (divisor != 0) {
// calculate
}
而不是捕捉异常
答案 2 :(得分:8)
由于你是一位自称为“新手”的人,我认为用你的代码指出一些更广泛的问题是个好主意。 (我知道这不是生产代码,但只是为了论证而假设它是。)
如果出现异常,如果检测到引起异常的情况,通常会更简单,更清晰,更有效。在这种情况下,如果您希望divisor
偶尔为零,最好在进行除法之前对其进行测试。
另一方面,如果异常完全出乎意料(即“bug”),最好的策略是让异常传播到最外层。此时,您的应用程序catch应捕获所有异常,记录异常堆栈跟踪并保释。
除了上一个项目符号外,抓住Exception
,RuntimeException
,Throwable
或Error
是个坏主意。这样做会捕获大量您可能不想捕获的异常。在这种情况下,由于您期望ArithmeticException
,因此您应该抓住这一点。
在财务应用程序中使用float
或double
很少是正确的。这些类型并不精确,但财务应用程序通常需要精确处理大量资金。
更一般地说,浮点数对于非专业人士(和新手)来说很难理解。人们期望持有的许多“真理”实际上并不成立。例如,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
。
答案 4 :(得分:2)
只有用整数除零才会引发ArithmeticException。 使用double或float除以零将导致 Infinity 。
答案 5 :(得分:1)
因为除以两个双打返回无穷大,但不抛出。您可以使用isInfinite()进行检查。但是,适当的解决方案(如前所述)是在划分前检查分母。
答案 6 :(得分:0)
没有人会试图让RuntimeException
从代码中抛出。可以(并且应该)轻松避免这些Exception
。