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

时间:2010-08-22 07:46:53

标签: java exception runtimeexception

我正在关注这个题为:The case against checked exceptions的SO讨论,但是我无法关注应该使用RuntimeException的地方以及它与普通Exceptions及其子类的不同之处。谷歌搜索给了我一个复杂的答案,也就是说,它应该用于处理编程逻辑错误,并且应该在没有正常情况发生时抛出,例如在switch-case结构的默认块中。

请在这里详细解释一下RuntimeException。感谢。

2 个答案:

答案 0 :(得分:18)

  

我无法完全遵循   应该使用RuntimeException

这可能是因为你正在查看一个论证,即人们对这一点的看法不一致。

  

和   它与正常情况有何不同   例外及其子类。

非常简单:Exception的所有子类(RuntimeException及其子类除外)都已检查,即编译器将拒绝您捕获的代码unelss或在方法签名。但是,RuntimeException的子类未选中

  谷歌搜索给了我一个复杂的答案,   也就是说,它应该被用来处理   编程逻辑错误和   没有Exception时应该抛出   通常应该发生,例如在   switch-case的默认块   构造

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

您链接的讨论是由某些人(包括我)认为检查过的异常导致错误代码而不应该被使用的观点引发的。由于您无法在编译器中禁用异常检查,因此执行此操作的唯一方法是仅使用 RuntimeException及其子类。

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

答案 1 :(得分:16)

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

  

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

     

决定是否使用已检查例外或未经检查的例外的基本规则是:

     
      
  • 使用已检查的例外情况,可以合理地预期来电者可以恢复。通过抛出已检查的异常,可以强制调用者在catch子句中处理异常或向外传播它。因此,声明抛出方法的每个已检查异常都是API用户的一个强有力的指示,即关联条件是调用该方法的可能结果。
  •   
  • 使用运行时异常来指示编程错误。绝大多数运行时异常都表示 precondition违规。违反前提条件的原因只是客户的API未能遵守API规范指定的合同。
  •   

以下是一个例子:

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

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

  

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

     

如果出现以下情况,那么负担是合理的:

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

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

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

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

另见

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

技术定义

未经检查的异常定义为RuntimeException及其子类,Error及其子类。它们不必在方法的throws子句中声明。

参考

相关问题