java异常继承图
- Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。 (来自jdk文档)
- Error一般是程序或者系统中比较严重的错误,只能通过重写代码等去解决。
- 异常又分为编译时异常(eg:ClassNotFoundException类找不到异常,FileNotFoundException文件找不到异常,SQLException sql异常等)和运行时异常(NullPointerException空指针异常,AirthmeticException运算非法异常,IndexOutOfBoundsException数组越界异常等)。
- 除了RuntimeException类及其之类外,所有的异常都是编译期异常,编译期的异常是我们必须进行显示处理的,如果不处理程序就无法继续编译执行。
- 运行期异常,我们可以不进行显示处理,也可以进行显示处理,不会影响程序的编译。如下图中的异常是可以通过编译的,在运行时才会报出错误。
- 我是这样理解运行时异常的,运行时异常就相当于一些小错误,不至于导致系统崩溃,只要我们在写代码时足够的严谨,就可以避免这些错误。(例如以下的代码,我们在进行除法运算之前,先判断除数是否为0,不为0才进行运算,这样就可以避免除数为0带来的错误)
- JVM对异常的处理:
如果在程序中出现问题,而我们不去处理,最终会由jvm做出默认的处理(把异常的名称,原因,问题相关的信息打印在控制台,同时结束程序),当我们对可能出现异常的部分进行了异常处理,那么程序就会继续运行下去。如下图,我们对做除法运算的语句进行了异常处理,它后面的代码int d=a+b正常的执行了,并且printStackTrace()方法给出了错误的信息。
异常的处理方案:
- 1.throws抛出异常
- 2.try…catch捕获异常
- try …catch语句通常写法:
try {
//可能出现问题的语句代码
}catch (异常名 变量) {
//针对问题的处理
}finally {
//必须执行的代码(如:释放资源)
}
- 当需要处理多个异常时的变形写法:
try {
//可能出现问题的语句代码
//语句1
//语句2
}catch (异常名 变量) {
//针对问题的处理
}catch(异常名 变量){
//针对问题的处理
}
...
注意:
- try里面的语句越少越好
- catch里面必须有内容,至少有简单点的提示语句
- 在catch中异常名写的原则:能明确的异常不要写其父类的异常名。
- 多个catch之间平级的异常先后顺序没有关系,但是当出现父子关系时,父类的异常写在最后。
- 存在多个catch的执行规则:一旦try里面的语句出现错误,就会将问题抛出去,和catch里面的异常进行匹配,执行catch里面的处理,然后try…catch就结束了,转而执行后面的代码。(如上面的语句1出现了问题,就会找对应的catch块,语句2就得不到执行)
- 变形写法2:(jdk1.7后)
try {
}catch (异常名1|异常名2|异常名3|...) {
}
这种写法异常名之间必须是平级的关系。
throws处理方式:
- 一般当我们没有权限或者我们处理不了某些异常时,才会选择使用throws的方案。
- 使用方法:在方法的声明上抛出,用于告诉调用者,我这里出现问题了,并由调用者来处理该异常。如下所示:
public void method() throws Exception{
}
- throw和throws的区别:
throws 用在方法声明后,可以跟多个异常名,表示将异常抛出,由方法的调用者来处理。throws表示出现异常的一种可能性,并不一定发生这种异常。
throw 在方法体内抛出,跟异常名对象,只能一个,表示抛出异常,执行throw则一定抛出了某种异常。
public class MyException {
public void method(){
int a = 10;
int b = 0;
if (b == 0)
throw new ArithmeticException();
else
System.out.println(a/b);
}
public static void main(String[] args) {
MyException me=new MyException();
me.method();
}
}
运行结果:
- finally
被finally控制的语句一定执行(但如果在finally执行之前jvm就退出了,finally中的代码不会被执行)
(个人学习总结,仅供参考,有错请指正,谢谢)