未经检查的异常最好作为已检查的异常处理

10

我意识到在Java中,关于选用受检异常(checked exceptions)或者非受检异常(unchecked exceptions)已经有大量的讨论探讨,我并不想再去重温整个争论的内容。

相反,我想提出一个非常具体的问题,这个问题在我阅读Joshua Bloch的《Effective Java》第二版时浮现出来。当我看书时,我注意到在第59项("避免不必要地使用受检异常")中,Joshua给出了一个Java API中使用受检异常的例子。特别是在Object中:

protected Object clone()
            throws CloneNotSupportedException

......然后他认为它应该是未检查异常。

如果使用 API 的程序员不能做得更好,那么未检查的异常会更适合。一个失败了这个测试的异常例子是 CloneNotSupportedException。它由 Object.clone 抛出,只应在实现了 Cloneable 接口的对象上调用 (第11项)。实际上,catch 块几乎总是具有断言失败的性质。异常的已检查特性对程序员没有任何好处,但它需要额外的工作并且使程序复杂化。

我寻找他是否有一个相反的例子,但是我找不到。所以我想问是否有人能够给出一个 Java API 的示例,它使用了未检查的异常,但是检查的异常可能是更好的选择,并解释原因。最好是一个真实的例子,但如果能够举出一个虚构的例子,那也可以很好地阐述问题。

编辑: 对于那些将此关闭为无建设性的人,我想要明确一点,我并不是在寻求意见、辩论、争论或扩展讨论。我也不是在进行民意测验。相反,我正在寻找关于如何权衡利弊的例子参考。(其中隐含着承认存在成本。)话虽如此,我对这个问题的性质是否可行持怀疑态度。我认为如果 Jon Skeet 都无法做到,那么这似乎是不可能完成的。所以也许你是正确的。如果必要,请关闭。

编辑: 虽然我并未被回答说服,但出于我的接受率考虑,我将这个答案授予了 Jon。

1个回答

13

没问题,很容易: Integer.parseInt 会抛出未检查的 NumberFormatException 异常。

然而,如果你需要解析可能存在问题的数据,你应该考虑捕获这个异常——你可能可以忽略那些错误的数据,或者报告错误并继续执行。Java没有 .NET 中 Int32.TryParse 这种可以 轻松忽略 错误数据的等价物。基本上,你需要知道在编译器没有提示的情况下需要捕获异常。烦人。


2
我完全同意。当你在编程时进入“区域”时,很容易忽略某些异常情况,等待弹出并喊出“pwn3d!”这可能是因为你忘记了捕获它,或者是因为你不知道你可能需要捕获它... - Fritz
感谢您的快速回复,Jon。你选择的例子并没有让我困扰。我很满意JavaDoc中提到了异常,并且很感激我可以选择处理问题的范围。你认为每个例子都会面临同样的权衡吗? - pohl
好问题。我肯定会因为交付了一个糟糕的产品而感到难过。如果将其作为已检查异常完全使我免于对不良输入进行强制性处理的负担,我想我会觉得这种想法很有吸引力。但我认为它并没有完全解决这个问题。至少你的例子足以让我摇摆不定。 - pohl
1
ArithmeticException(http://docs.oracle.com/javase/7/docs/api/java/lang/ArithmeticException.html)将是另一个类似的例子。 - emory
@JonSkeet,您对@emory在这里给出的示例有何感想?您是否希望编译器每次使用“/”或“%”运算符时都强制执行? - pohl
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接