1、Throwable
1)Throwable是所有异常的超类,包含2个子类: error(错误)和exception(异常)。
2)Throwable包含了其线程创建时执行堆栈的快照,它提供了printStackTrace()方法用来跟踪线程在执行中的获取堆栈的信息。
2、Error
1) Error类及其子类。是指程序在运行中,由于系统或者JVM出现的异常,导致程序被终止产生的一类异常。
如: StackOverflowError 栈溢出错误。OutOfMemoryError 内存不足错误。
3、Exception
1) 程序本身可以捕获并且可以处理的异常, Exception可分为运行时异常和编译时的异常。
运行时异常:
RuntimeException及其子类,表示JVM在运行期间可能出现的异常。JVM不会去检查此类异常,比如说NullPointerException 空指针异常,ArrayIndexOutBoundException数组下标越界异常, ClassCastException 类型强制转换异常。此类异常属于非检查异常。比如说,除0,会出现异常,我们应该通过代码来进行调整。
编译时异常:
Exception中除RuntimeException及其子类出现的异常称为编译时异常。JVM会检查此类异常,比如IOException,文件读取异常,ClassNotFoundException(没有找到指定的类的异常)。
处理方式:
1)通过throws在方法上声明抛出。
2)通过try..catch..捕获异常来进行处理。
4、检查型异常与非检查型异常
检查型异常:
检查型异常是编译器必须要处理的一类异常,除RuntimeException及其其他子类的异常不处理,其他的异常都属于检查型异常,如果不处理那么会编译不通过。 需要在方法名throws出去,或者自己用try{}catch来处理此类异常。
非检查型异常
非检查型异常又称为运行时异常,所有RuntimeException及其子类的异常可以均表示为运行时异常。 在程序运行中,由于自身逻辑而产生的一类异常,如NullPointerException, 下标越界异常。
5、 异常关键字
finally: finally关键字总是在try..catch之后执行,主要是起到回收资源的作用,如数据库连接释放等,如果在finally里有return或者throw等终止方法的语句,那么就不会跳回原方法执行,不处理throw的异常的话,会导致程序终止。
throw: throw关键字能够捕获到的异常,不处理并向上抛出,在方法里会被throws关键字给捕获到,在方法内部抛出一个Throwable类型的异常。任何java代码可以通过throw来抛出异常。
throws: throws关键字一般声明在方法上,用于可声明的异常。
6、异常处理机制
java异常的处理机制可分为: 捕获异常、抛出异常、声明异常。
注: 非检查异常(error,RuntimeException及其子类)不可使用throws关键字抛出。
一个方法出现编译时异常,就需要 try-catch/ throws 处理,否则会导致编译错误。
7、常见的异常面试题
- Error 和 Exception 区别是什么?
答: Error类型是 JVM相关错误,如系统崩溃、内存不足、栈溢出,等编译器对此类错误进行检测,一旦发生此类错误,应用程序会发生终止。
Exception是应用程序由于自身逻辑或者需要监测的异常造成的一类异常,通常遇到这种错误,应对其进行处理,使应用程序可以正常的进行。
- 运行时异常和一般异常(受检异常)区别是什么?
答: 运行时异常: 包含RuntimeException及其之类的一类异常,这类异常不会检查。
受检异常: JVM编译器需要监测的一类异常,是Exception异常除掉RuntimeException及其之类的 一类异常,需要对其进行处理才能编译通过,如IOException。
- JVM 是如何处理异常的?
答: 在一个方法中如果发生异常,这个方法会创建一个异常对象,并转交给 JVM,该异常对象 包含异常名称,异常描述以及异常发生时应用程序的状态。创建异常对象并转交给 JVM 的 过程称为抛出异常。可能有一系列的方法调用,最终才进入抛出异常的方法,这一系列方法 调用的有序列表叫做调用栈。JVM 会顺着调用栈去查找看是否有可以处理异常的代码,如果有,则调用异常处理代码。 当 JVM 发现可以处理异常的代码时,会把发生的异常传递给它。如果 JVM 没有找到可 以处理该异常的代码块,JVM 就会将该异常转交给默认的异常处理器(默认处理器为 JVM 的一部分),默认异常处理器打印出异常信息并终止应用程序。
- final、finally、finalize 有什么区别?
答: final 可以修饰类、方法、变量。final如果修饰类表示该类不能被继承,如果修饰方法,表示该方法不能被重写,若果修饰变量,表示该变量是常量,不能被重写赋值。
finally 一般用来处理异常必须要处理的代码块,一般可用来释放资源。
finalize 是jvm调用的一个方法,属于Object类的一个方法,是垃圾回收器在执行垃圾回收之前必须执行的清理方法。