请解释Java中的RuntimeException以及它应该在何处使用
我在SO上进行了这个伟大的讨论,标题为: 针对已检查exception的情况 ,但我无法遵循应该使用RuntimeException的位置以及它与正常exception及其子类的不同之处。 谷歌搜索给了我一个复杂的答案,也就是说,它应该用于处理编程逻辑错误,并且应该在没有正常情况发生时抛出,例如在switch-case结构的默认块中。
你能否在这里详细解释一下RuntimeException。 谢谢。
我无法遵循应该使用RuntimeException的地方
这可能是因为你正在看一个论点 ,即人们对这一点有不同意见。
以及它与普通exception及其子类的区别。
非常简单: 检查 Exception
所有子类( RuntimeException
及其子类除外),即编译器将拒绝您捕获的代码unelss或在方法签名中声明它们。 但是, 未选中 RuntimeException
子类。
谷歌搜索给了我一个复杂的答案,也就是说,它应该用于处理编程逻辑错误,并且应该在没有正常情况发生时抛出,例如在switch-case结构的默认块中。
这是传统的智慧,它表示对于程序可以有效处理的所有内容,您应该使用已检查的exception,因为编译器会强制您处理它们。 相反,程序通常不能有效地处理程序员错误,因此不必检查它们。 这就是Java Standard API使用RuntimeException
。
您链接的讨论是由某些人(包括我)认为检查exception会导致错误代码而不应该使用的。 由于无法在编译器中禁用exception检查,因此执行此操作的唯一方法是仅使用RuntimeException
及其子类。
IMO支持这种观点的一个观点是,“仅针对程序员错误使用未经检查的exception”的传统观点实际上主要是向后推理的合理化:没有代码安全性原因,编译器不应该强迫您处理程序员错误。 但是,像NullPointerException
和ArrayIndexOutOfBoundsException
这样的东西几乎可以在任何地方出现,如果这些被检查过,没有人会想要用Java编程。 因此,语言设计者必须为那些做出一个例外,并使它们不受限制。 为了解释这一点,他们想出了“未经检查的例程是针对程序员错误”的故事。
有效Java第2版的引言,第58项:对可恢复条件使用已检查的exception,对编程错误使用运行时exception
Java编程语言提供三种throwable:已检查的exception , 运行时exception和错误 。 程序员之间存在一些混淆,即何时适合使用各种throwable。 虽然决策并不总是明确,但有一些一般规则可以提供强有力的指导。
决定是使用已检查的exception还是未经检查的exception的基本规则是:
- 对于可以合理预期可以恢复调用者的条件,请使用已检查的exception 。 通过抛出已检查的exception,可以强制调用者在
catch
子句中处理exception或将其向外传播。 因此,声明抛出方法的每个已检查exception都是API用户的强有力指示,即关联条件是调用该方法的可能结果。- 使用运行时exception来指示编程错误 。 绝大多数运行时exception表示违反前提条件 。 违反前提条件的原因仅仅是客户端 API无法遵守API规范指定的合同。
这是一个例子:
- 尝试读取任意名称的文件时,该文件可能不存在。 当文件不存在时(例如,可能之前执行但随后意外删除),这不是严格的编程错误。 客户可能希望从中恢复。 因此,
FileNotFoundException
是一个经过检查的exception。 - 如果您将
null
字符串作为文件名,则应抛出NullPointerException
(或者可能是IllegalArgumentException
– 另一个有争议的争论)。 API的客户端应该提供有效的字符串值;null
不是。 就API而言,这是一个程序员错误,很容易被预防。 这两个例外都是运行时exception。
第59项:避免不必要地使用已检查的例外也提供了额外的指导:
检查exception是Java编程语言的一个很好的特性。 与返回码不同,它们迫使程序员处理exception情况,大大提高了可靠性。 也就是说,过度使用已检查的exception会使API的使用变得不那么令人愉快。 如果方法抛出一个或多个已检查的exception,则调用该方法的代码必须处理一个或多个
catch
块中的exception,或者必须声明它throws
exception并让它们向外传播。 无论哪种方式,它给程序员带来了巨大的负担。在以下情况下,负担是合理的:
- 正确使用API无法阻止exception情况, 并且
- 一旦遇到exception,使用API的程序员可以采取一些有用的操作。
除非这两个条件都成立,否则未经检查的exception更为合适。
所以这里是Effective Java 2nd Edition推荐的简短摘要:
- 应取消选中因API用户错误而发生的可预防exception。
- 无法合理处理的例外情况也应该取消选中 。
- 否则,应检查exception。
也可以看看
- 有效的Java第二版
- 项目58:对可恢复条件使用已检查的exception,对编程错误使用运行时exception
- 第59项:避免不必要地使用已检查的例外
- 第60项:赞成使用标准例外
- 第61项:抛出适合抽象的例外
- 第62项:记录每种方法抛出的所有exception
技术定义
未经检查的exception定义为RuntimeException
及其子类,以及Error
及其子类。 它们不必在方法的throws
子句中声明。
参考
- JLS 11.2编译时检查exception
相关问题
- 在Java中,何时应该创建一个已检查的exception,何时应该是运行时exception?
- 何时选择已检查和未检查的例外
- 针对已检查exception的案例
-
null
参数的IllegalArgumentException
或NullPointerException
?