未检查异常和运行时异常之间的区别

35

这是一个面试题。未检查异常和错误之间的主要区别是什么,因为它们都不会被捕获?它们将终止程序。


4
你的标题和问题所问的不一样。你是想了解RuntimeException和Error之间的区别还是想了解Unchecked和RuntimeException之间的区别? - Thomas Lötzer
3
不是“X和Y之间的区别”,而是“X与Y之间的区别”。确切地说,它是关于未检查异常和运行时异常之间的区别还是关于未检查异常和错误之间的区别? - BalusC
看起来这个面试问题被问了很多次:https://dev59.com/WXE85IYBdhLWcg3wnU0d - justkt
9个回答

64
如其名称所示,unchecked exceptions(未检查的异常)在编译时不会被检查,这意味着编译器不需要方法捕获它们或指定(使用throws)它们。属于此类别的类在JLS的11.2 Compile-Time Checking of Exceptions一节中有详细描述:

未检查异常类包括类RuntimeException及其子类和类Error及其子类。所有其他异常类都是已检查异常类。Java API定义了许多异常类,其中既包括了已检查异常也包括了未检查异常。程序员可以声明其他异常类,既包括已检查异常也包括未检查异常。请参见§11.5,以获取异常类层次结构及Java API和Java虚拟机定义的一些异常类的说明。

以下图片说明了异常层次结构:

alt text

Error及其子类是普通程序通常不会从中恢复的异常,并且如11.5 The Exception Hierarchy所述:

Error类是Throwable的一个独立子类,在类层次结构中与Exception不同,使程序可以使用以下习惯用法:

} catch (Exception e) {

为了捕获所有可能进行恢复的异常,而不是捕获通常无法恢复的错误,RuntimeException是未经检查的异常的子集(但未经检查的异常并不是RuntimeException的同义词,这点需要澄清)。


10
JavaDocs已经很好地总结了这些。

java.lang.RuntimeException:

RuntimeException是Java虚拟机正常运行期间可能抛出的那些异常的超类。

方法不需要在其throws子句中声明可能在方法执行期间但未被捕获的任何RuntimeException子类。

java.lang.Error:

一个错误是Throwable的一个子类,它指示严重问题,合理的应用程序不应该尝试捕获。大多数这样的错误都是异常情况。ThreadDeath错误虽然是“正常”情况,但也是Error的一个子类,因为大多数应用程序不应该尝试捕获它。
在其throws子句中,方法不需要声明可能在方法执行期间被抛出但未被捕获的任何Error子类,因为这些错误是不应该发生的异常情况。
请注意,“未经检查的异常”仅是RuntimeException的同义词。

http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html也提供了一个不错的描述,介绍了异常类型之间的区别。 - ChadNC
1
我认为将未经检查的异常视为 RuntimeException 的同义词是具有误导性的(并且不正确)。 - Pascal Thivent
@Pascal,怎么回事?我认为每当有人在Java中提到“未检查异常”,他们都是指某个RuntimeException子类,不是吗? - matt b
未检查异常是指非检查异常,未检查异常类包括类RuntimeException及其子类和类Error及其子类。我不知道该添加什么,未检查异常并不是RuntimeException的同义词。 - Pascal Thivent

5
注意:RuntimeException是一种未检查的异常。
未检查的异常是指在执行过程中可能会出现的异常,但没有被捕获,例如如果您不检查NullPointerException,则它始终是可能发生的,将导致程序终止。您可以通过将代码包装在try-catch中来检查它,但这不是强制性的(与需要强制处理异常的已检查异常不同)。
错误是指在执行过程中任何时候都可能发生的问题,不能真正捕获,因为它不是由特定方法调用等明确引起的。例如OutOfMemoryError或StackOverflowError。这两个都可能在任何时候发生,并且将导致应用程序终止。捕获这些错误没有意义,因为它们表示发生了无法恢复的情况。

4
不,相反的。运行时异常是未检查异常的一种。 - BalusC

3

错误指的是绝对不应该发生的基本问题。如果你遇到一个错误,那么一定发生了非常糟糕的事情。
另一方面,未经检查的异常(运行时异常)则是在某种程度上可以预期可能会出现异常,但没有合理的方法来处理它,因此使用try catch语句只会徒增麻烦和浪费空间。


2
RuntimeException是未检查异常的一个子集,而不是一个同义词。 - Pascal Thivent

3

已检查异常:

  • RuntimeExceptionError类之外,继承Throwable类的类被称为已检查异常。
  • 也称为编译时异常,因为这些类型的异常在编译时进行检查。这意味着如果我们忽略这些异常(不使用try/catchthrow处理异常),则会发生编译错误。
  • 它们是由代码无法控制的意外情况引起的可编程恢复性问题(例如,数据库关闭、文件I/O错误、错误输入等)
  • 我们可以使用try/catch块来避免它们。
  • 示例:IOExceptionSQLException

未检查异常:

  • 继承RuntimeException的类被称为未检查异常
  • 未检查异常不会在编译时检查,而是在运行时检查。这也是它们被称为"运行时异常"的原因
  • 它们也是可通过编程恢复的问题,但与已检查异常不同,它们是由代码流或配置中的错误引起的。
  • 示例: ArithmeticExceptionNullPointerExceptionArrayIndexOutOfBoundsException
  • 由于它们是程序错误,可以通过编写良好/明智的代码来避免。例如,“除以零”导致ArithmeticEceeption。我们可以通过一个简单的if条件-if(divisor!=0)来避免它们。同样,我们可以通过简单检查引用-if(object!=null)或使用更好的技术better techniques来避免NullPointerException

错误:

  • Error 指的是不被 try/catch 处理的无法恢复的情况
  • 例如: OutOfMemoryErrorVirtualMachineErrorAssertionError 等。

2

错误:这些是应用程序无法预见或恢复的异常情况,通常是外部的。

运行时异常:这些是应用程序内部的异常情况,通常也是无法预见或恢复的。

您可能需要阅读此文档


1

RuntimeExceptionsOutOfMemoryError等错误不需要被捕获,可以一直抛出直到到达main()函数终止应用程序。

其他异常如果没有被捕获或包含在throws列表中,将导致编译错误。


1

错误和运行时异常总称为未检查异常。

运行时异常是应用程序内部的异常情况,通常应用程序无法预料或恢复。这些通常表示编程错误,如逻辑错误或API的不当使用。

您可能想查看此链接,该链接解释了三种异常情况。

http://docs.oracle.com/javase/tutorial/essential/exceptions/catchOrDeclare.html

我希望这可以帮到您。

1
虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。 - ivarni
1
@ivarni 我已经更新了,希望有所帮助 :) 感谢您的反馈。 - grepit

0

java.lang.Error和java.lang.Exception都是java.lang.Throwable的子类。

java.lang.Error类表示由应用程序运行环境引起的错误。例如,当JVM耗尽内存或堆栈溢出时,会发生OutOfMemoryError或StackOverflowError。

而java.lang.Exception类表示主要由应用程序本身引起的异常。例如,当应用程序尝试访问null对象或尝试将不兼容的类类型强制转换时,会发生NullPointerException或ClassCastException。

java.lang.Exception的所有子类(除了RunTimeException的子类)都是已检查异常。例如,FileNotFoundException、IOException、SQLException、ClassNotFoundException等。

java.lang.RuntimeException和java.lang.Error的所有子类都是未检查异常。例如,NullPointerException、ArithmeticException、ClassCastException、ArrayIndexOutOfBoundsException、StackOverflowError、OutOfMemoryError等。

来源:错误与异常, 已检查与未检查异常


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接