请解释Java中的RuntimeException以及它应该在何处使用

eup*_*a83 10 java exception runtimeexception

我在SO上进行了这个伟大的讨论,标题为:针对已检查异常的情况,但是我无法遵循应该使用RuntimeException的地方以及它与正常异常及其子类的不同之处.谷歌搜索给了我一个复杂的答案,也就是说,它应该用于处理编程逻辑错误,并且应该在没有正常情况发生时抛出,例如在switch-case结构的默认块中.

你能否在这里详细解释一下RuntimeException.谢谢.

Mic*_*rdt 20

我无法遵循应该使用RuntimeException的地方

这可能是因为你正在寻找一个论点,即人们对这一点有不同意见.

以及它与普通异常及其子类的区别.

很简单:所有的子类Exception(除了RuntimeException和它的子类)的检查,即编译器unelss你赶上将拒绝代码或方法签名中声明它们.然而,子类RuntimeException未经检查.

谷歌搜索给了我一个复杂的答案,也就是说,它应该用于处理编程逻辑错误,并且应该在没有正常情况发生时抛出,例如在switch-case结构的默认块中.

这是传统的智慧,它表示对于程序可以有效处理的所有内容,您应该使用已检查的异常,因为编译器会强制您处理它们.相反,程序通常不能有效地处理程序员错误,因此不必检查它们.这就是Java Standard API使用的方式RuntimeException.

您链接的讨论是由一些人(包括我)认为检查异常会导致错误代码而不应该使用的.由于您无法在编译器中禁用异常检查,因此唯一的方法是 使用RuntimeException及其子类.

IMO支持这一观点的一个观点是,"仅针对程序员错误使用未经检查的异常"的传统观点实际上主要是向后推理的合理化:没有代码安全性原因,编译器不应该强迫您处理程序员错误.然而,像NullPointerExceptionArrayIndexOutOfBoundsException能突然出现在几乎任何地方,如果这些进行了检查,没有人会想用Java编程.因此,语言设计者必须为这些做出一个例外,并使它们不受限制.为了解释这一点,他们提出了"未经检查的例程是针对程序员错误"的故事.


pol*_*nts 17

来自Effective Java 2nd Edition的引言,第58项:对可恢复条件使用已检查的异常,对编程错误使用运行时异常

Java编程语言提供三种throwable:已检查的异常,运行时异常错误.程序员之间存在一些混淆,即何时适合使用各种throwable.虽然决定并不总是明确,但有一些一般规则可以提供强有力的指导.

决定是使用已检查的异常还是未经检查的异常的基本规则是:

  • 对于可以合理预期可以恢复调用者的条件,请使用已检查的异常.通过抛出已检查的异常,可以强制调用者处理catch子句中的异常或将其向外传播.因此,声明方法被抛出的每个已检查异常都是API用户的强有力指示,即关联条件是调用该方法的可能结果.
  • 使用运行时异常来指示编程错误.绝大多数运行时异常表示违反前提条件.违反前提条件的原因仅仅是客户端 API无法遵守API规范指定的合同.

这是一个例子:

  • 尝试读取任意名称的文件时,该文件可能不存在.当文件不存在时(例如,可能之前执行但随后意外删除),这不是严格的编程错误.客户可能希望从中恢复.因此,FileNotFoundException是一个检查异常.
  • 如果你给一个null字符串作为文件名,那么NullPointerException(或者可能是IllegalArgumentException另一个有争议的争论)应该抛出.API的客户端应该提供有效的字符串值; null不是.就API而言,这是一个程序员错误,很容易被预防.这两个例外都是运行时异常.

第59项:避免不必要地使用已检查的例外也提供了额外的指导:

检查异常是Java编程语言的一个很好的特性.与返回码不同,它们迫使程序员处理异常情况,大大提高了可靠性.也就是说,过度使用已检查的异常会使API的使用变得不那么令人愉快.如果方法抛出一个或多个已检查的异常,则调用该方法的代码必须处理一个或多个catch块中的异常,或者必须声明它throws是异常并让它们向外传播.无论哪种方式,它给程序员带来了重大的负担.

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

  • 通过正确使用API​​无法阻止异常情况,并且
  • 一旦遇到异常,使用API​​的程序员可以采取一些有用的操作.

除非这两个条件都成立,否则未经检查的异常更为合适.

所以这里是Effective Java 2nd Edition推荐的简短摘要:

  • 取消选中因API用户错误而发生的可预防异常.
  • 无法合理处理的例外情况也应该取消选中.
  • 否则,应检查异常.

也可以看看

  • 有效的Java第二版
    • 项目58:对可恢复条件使用已检查的异常,对编程错误使用运行时异常
    • 第59项:避免不必要地使用已检查的例外
    • 第60项:赞成使用标准例外
    • 第61项:抛出适合抽象的例外
    • 第62项:记录每种方法抛出的所有异常

技术定义

一个未经检查的异常被定义为RuntimeException和它的子类,并Error和它的子类.它们不必在方法的throws子句中声明.

参考

相关问题