Java中异常常见问题总结

问题1:try/catch/finally执行顺序问题

1.代码

  • 问下述代码能否编译通过?如果能,输出是?
public class Demo03 {


    public static void main(String[] args) {


        try {
            String s = null;
            
            return;
        }catch (Exception e){
            System.out.println("catch");
        }finally {
            System.out.println("finally");
        }
    }

}

2.分析

  • 上述代码可以编译通过,输出finally
    在这里插入图片描述

  • 这其实很简单,进入try代码块,执行return前的内容,然后没有发生异常则进入到finally代码块中的内容,然后再执行return

3.问题1.1

  • 下述代码能否编译通过?输出是?
public class Demo03 {
    public static void main(String[] args) {
        try {
            String s = null;
            System.exit(0);
//            return;
        }catch (Exception e){
            System.out.println("catch");
        }finally {
            System.out.println("finally");
        }
    }

}
  • 可以编译通过,什么都不输出
    在这里插入图片描述

  • 注意到代码System.exit(0);,遇到它的时候就不会再去执行finally中的代码,而是直接退出程序,这表示结束正在运行中的虚拟机

  • 一般来说finally中的代码是一定会被执行的,但是这是唯一的特殊情况,因为虚拟机都没了,后面的代码肯定都没办法执行

问题2:两类异常的不同处理方式

运行期异常,编译期异常

1.问题引入

  • 下述代码能否编译通过
public class ExceptionTest {
    
    
    public void doSomething() throws ArithmeticException{
        System.out.println("do");   
    }
    public static void main(String[] args) {
        ExceptionTest test = new ExceptionTest();
        test.doSomething();
    }
}
  • 可以通过,ArithmeticException是一个运行期异常,可以对其不做处理,最后会被抛出到虚拟机中处理

  • 下述代码能否编译通过?

public class ExceptionTest {
    public void doSomething() throws IOException {
        System.out.println("do");
    }
    public static void main(String[] args) {
        ExceptionTest test = new ExceptionTest();
        test.doSomething();
    }
}

  • 不能,IOException是一个编译期异常, 必须显式的向上抛出
    在这里插入图片描述

  • 修改上述代码,可以编译通过
    在这里插入图片描述

2小结

上述问题的本质是对于两种不同异常处理方式

  • checked exception:编译期异常,都是java.lang.Exception 的子类,必须进行处理,有两种处理方式
    • 继续向上抛出,消极的做法,直到跑到JVM
    • 主动的用try...catch进行处理
  • unchecked exception:运行期异常,都是java.lang.RuntimeException的子类,可以不出力

2.1异常类的继承结构

那我们如何能区分哪些异常属于编译期异常,哪些属于运行期异常呢?

在这里插入图片描述在这里插入图片描述在这里插入图片描述

问题3:try…catch捕获异常时的顺序问题

异常范围大的放下面,范围小的放前面

1问题

  • 下述代码,编译能否通过
public class ExceptionTest2 {

    public void doSomething01() throws IOException{
        System.out.println("do");
    }

    public static void main(String[] args) {

        ExceptionTest2 test = new ExceptionTest2();

        try {
            test.doSomething01();
        } catch (Exception e) {
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    
}
  • 不能
    在这里插入图片描述

  • 第一个catch是所有异常类的父类,不管try中发生何种异常都会进入到第一个catch的代码块中

  • 而只要进入了一个catch后面所有的catch就不会再被进入了,所有发生了编译错误

  • 当使用多个catch来捕获异常的时候一定要注意范围问题:异常范围大的放下面,范围小的放上面

  • 调整顺序后,编译通过
    在这里插入图片描述

  • 一般情况下,我们一般只用一个catch来捕获Exception类的异常即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值