Exception和Error区别

继承关系

Exception和Error均继承于Throwable。继承关系如下:

Throwable -> Exception -> RuntimeException
Throwable -> Error

Throwable

Throwable作为基类(不是抽象类),实现了对于异常类的基本操作。如

1
2
3
4
5
6
7
8
9
//构造方法
public Throwable() {}
public Throwable(String message) {}

//实例方法
public String getMessage() {}
public synchronized Throwable getCause() {}
public void printStackTrace() {}
public StackTraceElement[] getStackTrace() {}
  • 可以看到定义了若干构造方法,空构造方法和可传入错误 msg 的构造方法等
  • 提供了获取错误信息,错误对象,错误堆栈信息,打印堆栈等相关实例方法
  • 可看到 JAVA 中一切皆是对象,异常也只是一种特殊的封装对象

RuntimeException

RuntimeException 是 Exception 类的子类,表示正常操作也可能引起的运行时异常。所有的 RuntimeException 均是unchecked exceptions。即方法声明中不需要声明 throws 抛出的 exception。

如下 demo 代码可以看到,在方法中 throw RuntimeException,但是在方法声明中可声明 throws 的 RuntimeException,也可不声明。

1
2
3
4
5
6
7
private void runtimeExceptionExample() throws RuntimeException {
throw new RuntimeException();
}

private void runtimeExceptionExample2() {
throw new RuntimeException();
}

常见的运行时异常包括:RuntimeException、ArrayIndexOutOfBoundsException、NullPointerException、IllegalArgumentException等。

Checked Exception

任何 Exception 的子类,除去 RuntimeException 类型的异常,均是Checked Exceptions。Checked Exceptions 需要在方法体重声明 throws 的异常类型。

如下 demo 代码可以看到在方法中抛出了一个 IOException 类型的异常,由于 IOException 属于 Checked Exception,因此需要在方法声明中,声明抛出的异常类型即 throws IOException。

而第二个方法,在会在编译阶段即报错。

1
2
3
4
5
6
7
8
private void ioExceptionTest() throws IOException {
throw new IOException();
}

// 编译不过
// private void ioExceptionTest2() {
// throw new IOException();
// }

Error

Error 是 Throwable的子类,表明严重的错误和问题。一个合理的应用不应该去try和catch。大部分errors是非正常的情况。

ThreadDeath 类是一种正常情况的Error,但该类也是Error的子类,因为大部分的应用不应该尝试去catch这种异常。

一个方法内部,即使可能抛出error的异常,但是方法声明中不需要声明 throws 抛出的 error。因为大部分的 errors都是非正常的情况,是不应该发生的,也不应该去 catch。

这意味着,Error的子类也是非检查异常(unchecked exceptions)。

如下demo代码可以看到,在方法中 throw error,但是在方法声明中可声明throws的error,也可不声明。

1
2
3
4
5
6
7
private void unkownErrorTest() throws UnknownError {
throw new UnknownError();
}

private void unkownErrorTest2() {
throw new UnknownError();
}

总结

  • 异常总体分为运行时异常(RuntimeException)和检查异常(Checked Exception)。
  • RuntimeException 属于运行时抛出的可能发生的异常情况,在方法声明中不需要声明throws。
  • Checked Exception 在编译阶段即会进行检查,在方法声明中需要声明throws 的异常。
  • Error 属于一种特殊的异常,通常代表着非正常的、严重的问题发生。同样可被认为是非检查异常(unchecked exceptions)。
  • 如果不加 try catch,任何异常都会中断当前的代码运行。

参考资料

  1. JDK源码