java - 用于在检查异常和非检查异常之间做出决定的清晰简单的规则

标签 java exception

既然这方面有很多模糊之处,我们能否提出一些清晰、简单且易于使用的规则?

这是第一次尝试,这三个规则应该足以满足所有情况。

<小时/>

第一条规则基于通用原则,即方法的实现细节不应暴露给调用者:

规则 1: 检查的异常不应向调用者公开实现细节: 您可以这样测试它:如果您完全更改实现但仍然期望该方法履行其契约(就像在重构中),抛出异常仍然有意义吗? 如果是,那么它应该是一个已检查的异常,因为它不是实现细节,而是方法所填充的用例的一部分。 如果不是,则应取消检查异常,因为它是不应向调用者公开的实现细节。

如果根据规则 1 应检查异常(exception)情况,然后应用规则 2:

规则 2:由于检查异常是方法契约的一部分,因此违反方法契约的行为不能成为检查异常。 例如,此方法从其参数执行 sql 查询:

executeSqlQuery(String sqlQuery)

如果调用者提供的字符串不是 SQL 查询,那么他违反了该方法的输入条件,并且必须取消检查所产生的异常。

如果基于规则 2,异常看起来仍然像是已检查,则应用规则三来检查该方法是否遵循另一个最佳实践:单一职责原则

规则 3:方法应该只做一件事。 例如方法

List.get(int索引)

只正确地做了一件事:从列表中返回所需的元素。并且不尝试实现另一个常见用例:检查元素是否存在。 另一方面方法

findById(Long id) 抛出 RecordNotFoundException

错误地尝试混合这两个函数,从而迫使所有调用者始终考虑找不到记录时的用例,即使他们知道记录存在。

<小时/>

是否缺少某些规则,或者我们可以进一步简化和澄清规则吗?

<小时/>

背景: 关于这个话题有很多不同的观点。有很多“激进”解决方案的支持者,例如永远不要使用检查异常(一些 Java 书籍或 C# 设计者),或者几乎所有内容都应该是检查异常(java.io 包中的 IOException 或 JDBC 中的 SQLException)。 至少相同数量的 View 建议使用这两种类型,但提供了主观和模糊的规则来在它们之间做出决定,而没有冗长的解释,而这些解释往往会丢失,而不是带来更多的困惑(例如:如果调用者有理由这样做)从异常中恢复而不是应该检查。再次尝试调用是否是合理的恢复?对于某些客户端来说可能是。“合理”和“恢复”这两个词太含糊了。)

最佳答案

嗯,这个问题在官方 Java Tutorials 中有答案,事实上:

Here's the bottom line guideline: If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception.

对我来说,这看起来是一个非常清晰、简单的规则。

编辑:您的背景编辑很好地解释了您的困惑和沮丧。如果你愿意,我可以想出一个更简单的规则:

Always be usable. Try to be practical where possible. Strive to be consistent.

重点是,异常处理是可能抛出异常的方法的用户必须执行的操作。遗憾的是,Java 强制编写该方法的人为该方法的用户做出选择。因此,我稍微倾向于“从不检查”方面,因为您的方法将始终可用。对于某些情况,例如网络 I/O,强制用户构建一些错误处理可能确实实用,但情况并不常见。如果您问自己嗯,我的最后 400 个方法都抛出了 RuntimeError,现在应该抛出一个已检查的异常吗?,获得一致性可能使您的库的使用更加实用

遗憾的是,这条规则更容易,但并不更清晰,因为至少实用一致是非常主观的概念。所以你现在遇到的问题实际上是风格的问题。

关于java - 用于在检查异常和非检查异常之间做出决定的清晰简单的规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29331615/

相关文章:

java - 尽管正在初始化对象,但仍出现空对象引用错误

java - 使用java从字符串中仅删除嵌套的大括号

List.add()期间发生java.util.ConcurrentModificationException

java - 使用 mod 对 id 进行分区的良好哈希函数

java - 如何使用 Nexus 存储库解决 Maven 中的依赖关系错误

java - Intellij IDEA JavaFX Scene Builder 与应用程序其余部分的分辨率不同

C++ 异常 : out_of_range_error from Programming Principles

java - Try Catch 不断循环而不是请求另一个值?

java - 处理 Spring Security Authentication Provider 中抛出的 BadCredentialsException

java - 我的测试用例中预期异常的正确组合是什么?