[toc]
异常体系分类#
Q: Throwable 和 Error的关系#
A: Throwable是Error(错误)的基类,也是Exception的基类
1个好图,可看到常见的异常和error
Q: Error和Exception的关系#
A:
- Error一般是会直接引起jvm出错的错误,例如Java虚拟机运行错误等,如果出现了当前线程会无法继续运行。
- Excpetion是程序本身可以处理的异常。发生后还能正常运行。
Q: Error可以被catch捕捉吗?#
A: 只要是Throwable和其子类都是可以throw和catch的。 但是不建议捕捉Error。
异常体系还可以分为这2类:#
-
unchecked exception(非检查异常)
也称运行时异常(RuntimeException),比如常见的NullPointerException、IndexOutOfBoundsException。对于运行时异常,java编译器不要求必须进行异常捕获处理或者抛出声明,由程序员自行决定。 -
checked exception(检查异常,编译异常)
也称非运行时异常(运行时异常以外的异常就是非运行时异常),java编译器强制程序员必须进行捕获处理,比如常见的IOExeption和SQLException。对于非运行时异常如果不进行捕获或者抛出声明处理,编译都不会通过。
异常捕捉和返回#
Q: return-finally陷阱1: finally能通过修改变量,来更新return的变量值吗#
1 | int f() { |
A: 不能, f返回1。
Q: return-finally陷阱2: finally里也return时,返回哪个?#
1 | int f() { |
A:返回finally里的,返回2。
Q: 什么情况下finally块里的步骤可以不执行?#
A: 只有在finally之前调用System.exit(0)退出jvm, 才能让finally不执行。
Q: 先捕捉父类异常,再捕捉子类异常,会发生什么?#
1 | try { |
A: 直接编译就错误了。 catch是会按顺序的且匹配1个就不再往下匹配,编译器因此识别出RuntimeExcpetion永远不会被捕捉到,便提前报错。
Q:throw异常的时候,在finally中做return,那么异常还会抛出吗?#
1 | static int f() { |
A:
不会,返回-1.
即finaly中做return会中断throw
因此永远不要在finally中去做return操作
受检异常相关问题#
Q: 子类覆写基类方法时 , 能throws基类方法中不存在的异常吗?#
像下面这样:
1 | class A{ |
A: 不行,直接编译报错。 即子类覆写父类方法时, throws关键字后面跟的异常必须是小于等于父类方法异常的。
Q: finally中调用某资源的close时,也会抛出受检异常, 除了在finally里做try-catch,还能怎么做?#
像下面这样,finally又有catch,就很难看:
1 | TryWithResource tryWithResource = new TryWithResource(); |
A:如果是JDK1.7,可以用try-with-resource语法。
需要资源类实现AutoCloseable接口, 并在try的时候在try括号后面跟上资源的创建,如下:
1 | public static void main(String[] args) { |
这样就不需要写finally,finally+close会通过编译器给我们自动加上。
Q: 线程抛出异常的话该怎么捕捉?#
A: 实现异常处理接口MyUnchecckedExceptionhandler
1 | public class MyUnchecckedExceptionhandler implements UncaughtExceptionHandler { |
然后把实现类设置给对应线程。
1 | Thread t = new Thread(new ExceptionThread()); |
除此之外还有6种方法可以设置,详见链接