在API中查看已检查的预测并不罕见,其中一个最着名的示例是Closeable.close()
中的IOException
。经常处理这个异常真让我烦恼。更令人讨厌的例子是我们的一个项目。它由几个组件组成,每个组件声明特定的已检查异常。问题(在我看来)是在设计时,并不确切知道某些例外是什么。因此,例如,组件Configurator
声明为ConfiguratorExeption
。当我问为什么不使用未经检查的异常时,我被告知我们希望我们的应用程序是健壮的,而不是在运行时。但它因为:
try-catch
语句中执行的。我认为,这是一种反复出现的模式。但仍然检查过的异常在API中被广泛使用。这是什么原因?是否有某些类型的API更适合检查异常?
答案 0 :(得分:2)
只有在 1) 例外 的事情中才会抛出已检查的例外情况它们是成功规则的例外,大多数可怜的异常抛出都是可怕的客户的防御性编码和 2) 可操作 的习惯。如果发生某些事情,API的客户端不可能以任何方式影响它,使其成为RuntimeException。
答案 1 :(得分:2)
围绕这个问题已经有很多controversy。
看看这篇关于该主题的经典文章http://www.mindview.net/Etc/Discussions/CheckedExceptions
我个人倾向于支持自己使用Runtime
例外,并开始考虑在您的API中使用已检查的例外是一个坏主意。
事实上,一些非常流行的Java API已经开始做同样的事情了,例如, Hibernate 从版本3中删除了对运行时的已检查异常的使用, Spring 框架也支持在已检查的异常中使用Runtime。
答案 2 :(得分:2)
大型库的一个问题是它们没有记录可能抛出的所有异常,所以如果一个未记录的RuntimeException恰好是从你没有“拥有”的深层代码中抛出的话,你的代码可能会随时轰炸”
通过明确声明所有这些,至少使用所述库的开发人员有编译器帮助正确处理它们。
没有什么比在早上3点进行法医分析更能发现某些情况引发了这种未申报的例外情况。
答案 3 :(得分:1)
对此事有不同的看法,但我倾向于按如下方式查看:
例如,它完全属于典型环境的范围,在某些特殊情况下 - 但是相当可预测 - 条件下,关闭文件可能会导致I / O错误(在磁盘关闭时将缓冲区刷新到文件已满)。因此,让Closable抛出一个经过检查的IOException的决定可能是合理的。
另一方面,标准Java API中有一些例子,其决策不太可靠。我会说,在检查异常时,XML API通常过于繁琐(为什么找不到你真正希望在典型应用程序中发生和处理的XML解析器......?),反思API也是如此(你通常真的希望找到类定义,不管它们不是......都不能发挥作用。但许多决定都是有争议的。
一般情况下,我同意应该取消选中“配置异常”类型的异常。
请记住,如果你正在调用一个方法来声明一个已检查的异常,但你“真的不希望它被抛出,并且真的不知道如果它被抛出该怎么办”,那么你可以通过编程方式“耸耸肩“并将其重新投射到RuntimeException或Error ...
答案 4 :(得分:0)
事实上,您可以使用Exception tunneling,以便通用异常(例如您的ConfiguratorException)可以提供有关错误的更多详细信息(例如FileNotFound)。
一般情况下,我会对此提出警告,因为这可能是leaky abstraction(没有人应该关心你的配置器是否试图从文件系统,数据库,网络或其他任何方面提取数据)
如果您使用的是检查异常,那么至少您知道您的抽象漏洞的位置和原因。恕我直言,这是一件好事。