继承关系
Exception和Error均继承于Throwable。继承关系如下:
Throwable -> Exception -> RuntimeException
Throwable -> Error
Throwable
Throwable作为基类(不是抽象类),实现了对于异常类的基本操作。如
1 | //构造方法 |
- 可以看到定义了若干构造方法,空构造方法和可传入错误 msg 的构造方法等
- 提供了获取错误信息,错误对象,错误堆栈信息,打印堆栈等相关实例方法
- 可看到 JAVA 中一切皆是对象,异常也只是一种特殊的封装对象
RuntimeException
RuntimeException 是 Exception 类的子类,表示正常操作也可能引起的运行时异常。所有的 RuntimeException 均是unchecked exceptions。即方法声明中不需要声明 throws 抛出的 exception。
如下 demo 代码可以看到,在方法中 throw RuntimeException,但是在方法声明中可声明 throws 的 RuntimeException,也可不声明。
1 | private void runtimeExceptionExample() throws RuntimeException { |
常见的运行时异常包括:RuntimeException、ArrayIndexOutOfBoundsException、NullPointerException、IllegalArgumentException等。
Checked Exception
任何 Exception 的子类,除去 RuntimeException 类型的异常,均是Checked Exceptions。Checked Exceptions 需要在方法体重声明 throws 的异常类型。
如下 demo 代码可以看到在方法中抛出了一个 IOException 类型的异常,由于 IOException 属于 Checked Exception,因此需要在方法声明中,声明抛出的异常类型即 throws IOException。
而第二个方法,在会在编译阶段即报错。
1 | private void ioExceptionTest() throws 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 | private void unkownErrorTest() throws UnknownError { |
总结
- 异常总体分为运行时异常(RuntimeException)和检查异常(Checked Exception)。
- RuntimeException 属于运行时抛出的可能发生的异常情况,在方法声明中不需要声明throws。
- Checked Exception 在编译阶段即会进行检查,在方法声明中需要声明throws 的异常。
- Error 属于一种特殊的异常,通常代表着非正常的、严重的问题发生。同样可被认为是非检查异常(unchecked exceptions)。
- 如果不加 try catch,任何异常都会中断当前的代码运行。
参考资料
- JDK源码