Java未选中/已检查exception澄清
我一直在阅读关于未经检查和已检查的问题,没有一个在线资源真正清楚这些差异以及何时使用这两者。
根据我的理解,它们都会在运行时抛出,它们都代表超出逻辑预期范围的程序状态,但必须明确捕获已检查的exception,而未经检查的exception则不会。
我的问题是,假设为了论证我有一个方法来划分两个数字
double divide(double numerator, double denominator) { return numerator / denominator; }
以及需要在某处使用divison的方法
void foo() { double a = divide(b, c); }
谁负责检查分母为零的情况,是否应该检查或取消检查exception(忽略Java内置的分区检查)?
那么,除法方法是否被声明为或
double divide(double numerator, double denominator) throws DivideByZeroException { if(denominator == 0) throw DivideByZeroException else ... } void foo() { try{ double a = divide(b, c); } catch(DivideByZeroException e) {} }
或者没有经过检查的例外,原样如下:
double divide(double numerator, double denominator) { if(denominator == 0) throw DivideByZeroException else ... } void foo() { if(c != 0) double a = divide(b, c); }
并允许foo通过零检查划分?
这个问题最初出现在我写的数学程序中,用户输入数字和逻辑类进行计算。 我不知道GUI是否应该立即检查不正确的值,或者内部逻辑是否应该在计算期间捕获它们并抛出exception。
有趣的话题确实!
在阅读并尝试了大量处理一般错误和exception的方法后,我学会了程序员错误和预期错误之间的区别。
程序员错误永远不应该被捕获,而是早期和艰难地崩溃(!)。 程序员错误是由逻辑错误引起的,应该修复根本原因。
应始终捕获预期的错误 。 此外,当捕获到预期错误时,必须为用户显示一条消息。 这有一个重要的含义 – 如果预期的错误不应该显示错误,最好检查方法是否会抛出而不是让它抛出。
所以应用到你的例子我会想“这应该如何看待用户?”
- 如果应该显示错误消息(在浏览器输出,控制台,消息框中),我会抛出exception并将其尽可能接近UI并输出错误消息。
- 如果不显示错误消息,我会检查输入而不是抛出。
旁注:我从不抛出DivideByZeroException
和NullPointerException
– 我让JVM为我抛出这些东西。 在这种情况下,您可以酿造自己的exception类或使用合适的内置检查exception。
我最喜欢讨论Java中已检查和未检查exception之间的哲学差异:
假设由于数学运算而抛出了已检查的exception。 除法(根据你的post)。
这意味着每个整数除法应出现在try块中!
实际上,division可以抛出一个ArithmeticException,它是未经检查的exception,所以不需要捕获它。
实际上你不应该抓住它,因为它是一种特殊情况,通常只能通过代码校正来解决。
在您的情况下,您的代码应该在实际除以零之前完成某些操作。
如果你已经达到允许实际除零的步骤,那么你无能为力。 该程序是错误的,最好修复,而不是试图以某种方式通过抛出/捕获exception来伪装它
Javaexception仅由编译器检查,但java设计者决定将它们分成多个类别,基本上涉及扩展的超类
-
java.lang.Exception
– 称为已检查的exception -
java.lang.RuntimeException
称为UNcheckedexception – 作为奖励java.land.RuntimeException扩展java.lang.Exception(以简化catch
块中的处理,而不仅仅是) -
java.lang.Error
– 错误,也是未经检查的,很少需要由用户空间代码处理,但了解它们及其差异是一个重要的优点。 它们包括(最着名的):链接错误,堆栈溢出,内存不足,断言错误 -
java.lang.Throwable
– 经过检查! 所有例外的母亲,很少需要直接将其子类化,但有些确实是出于未知原因
因此,需要声明exception并处理正确的传播(仅在编译级别),未经检查的那些是自动传播的,并且除非需要,否则不期望开发人员提供处理。
通常预期会发生检查,并且需要在java中已经非常冗长的代码。
最糟糕的做法包括: catch (Throwable t){}
,由于很多原因,除非必要,否则通常不会处理错误,并且大多数错误通常会导致线程死亡。
简短的回答,因为一些利弊被命名:这是个人或组织风格的问题。 没有一个在function上优于另一个。 您(或您的项目)必须自行决定是使用已检查或未检查的exception,还是两者都有。
Oracle的Java Tutorial建议您对应用程序可以从中恢复的所有错误使用已检查的exception,并对应用程序无法从中恢复的错误进行未经检查的exception。 但根据我的经验,大多数应用程序可能会从大多数(可能不是在启动时)exception中恢 失败的操作将被中止,但应用程序仍然存在。
我宁愿只使用已检查的exception或未经检查的exception。 混合可能导致混淆和使用不一致。 务实。 在你的情况下做有意义的事情。
永远不要显式抛出RuntimeException
。 如果您认为您需要让运行时执行此操作而不是使用throw
。
- javax.naming.NoInitialContextException – Java
- java.lang.ArrayIndexOutOfBoundsException:length = 0; index = 0 – 数据库阅读 – Android
- Java PatternSyntaxException:字符串替换非法重复?
- postgresql错误:由于用户请求而取消语句
- Hadoop ClassNotFoundException
- RSA BadPaddingException:数据必须以零开头
- 例外:向容器添加窗口如何解决?
- 如何解决此错误java.util.ConcurrentModificationException
- 在try \ finally块中是否存在这样的情况,finally将不会被执行?