0%

Java的Error和Exception

简单记录一下Java的ErrorException的区别,以及checked和unchecked的区别。

Throwable (1)

Error和Exception (2)

Error类主要代表程序运行的环境出错。例如OutOfMemoryError表示JVM内存耗尽;StackOverflowError表示栈溢出。不能用try-catch来处理Error(即使能用catch住,也无法recover)。如上图所示,Error都是unchecked(见下文)。

Error不同,Exception类主要代表程序本身的错误,可以使用try-catch处理。Exception分为两种:checked和unchecked。

checked和unchecked (3)

  • checked:编译器在编译阶段会检查这类异常,它强迫程序员要么用try-catch处理,要么使用throws声明抛出。这也是”checked”这个词的意义。Checked异常一般是可以被recover的。

  • unchecked:编译器在编译阶段不会检查这类错误。它包含ErrorRuntimeException(及其子类)。1.Error主要代表程序运行的环境出错(比如OutOfMemoryErrorStackOverflowError),所以只有运行时才可能发生。2.RuntimeException主要表示编程错误,例如程序运行时发生除零错误会抛出ArithmeticException;访问数组越界会抛出ArrayIndexOutOfBoundsException,访问空指针会发生NullPointerException。这主要是程序员的问题。它们可能发生在任何地方,也可能非常多。假如把它们归入checked类,那么几乎所有的函数都需要catch它们或声明throws它们,使得程序很不简洁。并且,假如你声明throws一个ArithmeticException,相当于告诉你的调用者:我这段程序可能抛出除零异常。这不是你应该避免的吗?难道你知道哪里有可能还不检查被除数?另外,unchecked异常也很难被recover:环境出错自不必说;编程错误如何recover呢?比如你调用了一个函数,它抛出了除零异常,或者数组越界。

总之,unchecked错误里,Error是环境错误;RuntimeException是编程错误;都难以recover。所以,一般来说:

  • 不要抛出RuntimeException,也不要继承它定义异常类。
  • 一个错误,你的调用者catch到它时,若可能recover(比如IO异常,可以重试),就把它定义为checked;否则,调用者不能recover,则定义为unchecked。
写的不错,有赏!