1. 怎样理解 Throwable
Throwable
是所有异常类的父类。Throwable
类有两个主要参数:一个是 message,表示异常信息;另一个是 cause,表示触发该异常的其他异常。异常可以形成一个异常链,上层的异常由底层的异常触发,cause 表示底层异常Throwable
还有一个public
方法用于设置 cause:Throwable initCause(Throwable cause)
Throwable
的某些子类没有带 cause 参数的构造方法,就可以通过这个方法来设置,这个方法最多只能被调用一次- 在所有构造方法的内部,都有一句重要的方法调用:
fillInStackTrace()
,它会将异常栈信息保存下来,这是我们能看到异常栈的关键
2. Throwable
中常用的用于获取异常信息的方法有哪些
void printStackTrace()
,打印异常栈信息到标准错误输出流void printStackTrace(PrintStream s) / void printStackTrace(PrintWriter s)
,打印栈信息到指定的流String getMessage()
,获取设置的异常message
Throwable getCause()
,获取异常的cause
StackTraceElement[] getStackTrace()
,获取异常栈每一层的信息,每个StackTraceElement
包括文件名、类名、方法名、行号等信息
3. 异常类体系图
4. 异常类的体系是怎样的
Throwable
是所有异常类的基类,它有两个子类:Error
和Exception
Error
表示系统错误或资源耗尽,即不可控的内部原因,由 Java 系统自己使用,应用程序不应抛出和处理。常见的子类有:VirtualMachineError
、OutOfMemoryError
、StackOverflowError
Exception
表示应用程序错误,即不可控的外部原因,它有很多子类,应用程序也可以通过继承Exception
或其子类创建自定义异常。常见的子类有:IOException
、RuntimeException
、SQLException
5. 怎么理解未受检异常和受检异常
- 未受检异常包括:
RuntimeException
及其子类和Error
及其子类 - 受检异常包括:
Exception
及其除了RuntimeException
之外的其他子类 RuntimeException
比较特殊,它的名字有点误导,因为其他异常也是运行时产生的,它表示的实际含义就是未受检异常。- 受检和未受检的区别在于 Java 如何处理这两种异常
- 对于受检异常,Java 会强制要求程序员进行处理,否则会有编译错误
- 而对于未受检异常则没有这个要求。有点类似于编译时和运行时的区别
6. 为什么定义这么多不同的异常类
- 这么多不同的异常类其实并没有比
Throwable
这个基类多多少属性和方法,大部分类在继承父类后只是定义了几个构造方法,这些构造方法也只是调用了父类的构造方法,并没有额外的操作 - 之所以定义这么多不同的异常类主要是为了名字不同。异常类的名字本身就代表了异常的关键信息,无论是抛出异常还是捕获异常,使用合适的名字都有助于代码的可读性和可维护性
7. 怎样自定义异常
- 一般是继承
Exception
或者它的某个子类 - 如果继承的父类是
RuntimeException
或它的某个子类,那么此时自定义异常也是未受检异常 - 如果继承的父类是
Exception
或它的除了RuntimeException
之外的其他子类,那么此时自定义的异常是受检异常