try-catch 除以零
我的问题是关于一个简单的除以零示例的 try-catch 块。你看到第一行的 try 了吗?如果我将这两个变量中的任何一个转换为 double,程序将无法识别 catch 块。在我看来,无论我是否强制转换,都必须执行 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");
}
}
My question is about try-catch blocks on a simple division by zero example. You see the first line of try? If I cast any of those two variables to the double the program does not recognize the catch block. In my opinion, whether I cast or not only the catch block must be executed. What is wrong on this code?
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");
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
除以零对于浮点数有效。
这些“数字”在 IEEE 754 中得到了正确的定义。
另一方面,整数除以零会抛出异常,因为不能将无穷大表示为 int。
Divide by zero is valid for floating point numbers.
These "numbers" are properly defined in IEEE 754.
Integer division by zero, on the other hand, throws because one cannot represent infinity as an
int
.我建议验证:
而不是捕获异常
I'd suggest verifying:
rather than catching an exception
由于您自称是“新手”,因此我认为指出您的代码的一些更广泛的问题是个好主意。 (我知道这不是生产代码,但为了论证,我们只是假设它是。)
如果预期会出现异常,那么如果您检测到会引发异常的情况,通常会更简单、更清晰、更高效到例外。在这种情况下,如果您预计除数偶尔为零,最好在除法之前对其进行测试。
另一方面,如果异常是完全意外的(即“错误”),最好的策略是让异常传播到最外层。此时,您的应用程序 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 块就很难正确执行操作。例如,在这种情况下,远程 catch 块无法确定地诊断被零除的原因。ArithmeticException
可能来自应用程序的不同部分,并且可能不是甚至被零除!解决方法是显式抛出更具体的异常。Since you are a self-proclaimed "newbie", I think it would be a good idea to point out some broader issues with your code. (I know it is not production code, but just lets assume for the sake of argument that it was.)
If an exception is expected, it is usually simpler, clearer and more efficient if you detect the condition that will give rise to the exception. In this case, if you expect
divisor
to occasionally be zero it is better to test it before doing the division.On the other hand, if an exception is totally unexpected (i.e. a "bug") the best strategy is to let the exception propagate to the outermost level. At that point your application catch should catch all exceptions, log the exception stacktrace and bail out.
Apart from the previous bullet, it is a bad idea to catch
Exception
,RuntimeException
,Throwable
orError
. Doing this will catch a large number of exceptions that you probably don't intend to catch. In this case, since you are expecting anArithmeticException
, you should catch just that.It is rarely correct to use
float
ordouble
in financial applications. These types are not exact, but financial applications typically require quantities of money to be handled exactly.More generally, floating point numbers are inherently hard for lay people (and newbies) to understand. A lot of the "truths" that people expect to hold actually don't hold. For example, a floating point calculation of
1.0/3.0 + 1.0/3.0 + 1.0/3.0
does not give1.0
. Similarly (as you discovered) division by zero behaves differently. If you want to use floating point safely, you need to understand the pitfalls.EDIT elaborating the first point in response to @Jay's comment.
First, I deliberately used the word "usually". There are cases where avoiding throwing the expected exception achieves nothing.
Having said that, you often don't want a generic "expected" exception to happen even if your application cannot deal with the situation immediately. For example, if the OP's code was part of something larger, it may be better to explicitly throw
IllegalArgumentException
(if this is a violation of an API contract) or some checkedUserEnteredRubbishException
if we know that this is a result of bad user input (and there is some opportunity to report / correct it).The fact that we are "expecting" an exception means by definition that we know more about it than (say) a generic
ArithmeticException
would say. If we allow a generic exception to propagate, it makes it harder for a catch block many stack frames to act appropriately. In this case for example, the remote catch block could not diagnose the cause of the divide-by-zero with any certainty. TheArithmeticException
might have come from a different part of the application, and might not even be a divide-by-zero! The way to address is to explicitly throwing a more specific exception.答案在于您的程序自己的输出 - 它为
结果
打印“Infinity”。这是因为 Java 只不允许整数除以零 - 浮点除以零是合法的并会产生无穷大。请参阅 Double 的文档浮动
POSITIVE_INFINITY
和NEGATIVE_INFINITY
常量。The answer lies in your program's own output - it prints "Infinity" for
result
. This is because Java only disallows integer division by zero - floating point division by zero is legal and producesInfinity
.See the documentation of Double and Float for the
POSITIVE_INFINITY
andNEGATIVE_INFINITY
constants.只有用整数除以零才会引发 ArithmeticException。
使用 double 或 float 除以零将得到无穷大。
Only division by zero with integers will raise an ArithmeticException.
Division by zero with double or float will result in Infinity.
因为除以两个双精度数会返回 Infinity,但不会抛出异常。您可以使用 isInfinite () 来检查这一点。然而,适当的解决方案(如前所述)是在除法之前检查分母。
Because dividing two doubles returns a Infinity, but doesn't throw. You can use isInfinite() to check for this. However, the appropriate solution (as already noted) is to check the denominator before the division.
任何人都不应期望自己的代码会抛出 RuntimeException。这些
异常
可以(并且应该)轻松避免。No one should try to expect
RuntimeException
to be thrown from their code. TheseException
s can be (and should be) avoided easily.