请解释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”的传统观点实际上主要是向后推理的合理化:没有代码安全性原因,编译器不应该强迫您处理程序员错误。 但是,像NullPointerExceptionArrayIndexOutOfBoundsException这样的东西几乎可以在任何地方出现,如果这些被检查过,没有人会想要用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,或者必须声明它throwsexception并让它们向外传播。 无论哪种方式,它给程序员带来了巨大的负担。

在以下情况下,负担是合理的:

  • 正确使用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参数的IllegalArgumentExceptionNullPointerException