2.全面理解java异常机制

在理想状态下,程序会按照我们预想的步骤一步一步的执行,但是即使你是大牛,你也不可避免出错,所以java为我们提供了异常机制。本文将会从以下几个方面介绍java中的异常机制:

  • 异常机制的层次结构
  • 异常的处理过程
  • 抛出异常
  • 捕获异常
  • 异常机制的实现细节
  1. 异常机制的层次结构
    在java程序设计语言中,所有的异常对象都是派生于Throwable类,一般情况下,如果java中内置的异常类不能满足需求,可以自定义异常类只需要继承与Throwable类即可,下面是java 中的异常层次结构:
    在这里插入图片描述
    error类表示java内部错误,例如jvm出错或者内存不足等,这层一般不用我们关心(其实我们也无可奈何,如果出现此种问题),一旦出现此种错误程序会自动结束。
    我们主要还是需要研究Exception类及其子类,Exception主要有两个子类,IOException和RuntimeException我们一个个看。IOException是IO错误类问题导致的异常,是可预知的,例如由于文件不存在而打开文件失败引起的异常等。RuntimeException类异常表示运行时异常,例如数组下标越界,访问空指针等,是不可预知的,但是这类异常于编写程序时应当予以避免,例如你可以使用if(a==null)…,加以检查避免。
    以上从一种角度对这些主要的异常类进行了分类,其实我们还有一种分类方式,按照是否是检查类异常(checked)进行分类,什么是检查类异常?检查类异常(checked)就是指编译器会检查当前的代码块中,判断是否有这么一条语句在程序执行时可能产生异常,如果有就会建议程序员处理。(实际上你必须处理,不然编译不会通过),在以上的分层中,error类和RuntimeException类属于非检查异常类(unchecked),而 IOException属于检查类异常 。

异常 try catch finally 与return 的执行顺序

一般情况下,程序执行到try里面的内容一定会执行finally里面的内容。如果在try或者catch里面遇到return,那么函数在执行完return后面的表达式之后,会先去执行finally里面的语句块,然后再结束方法体。但有一种特殊情况,如果在try里面有System.exit(0)这样的语句,System.exit(0)是终止Java虚拟机JVM的,连JVM都停止了,所有都结束了,当然finally语句也不会被执行到。现在考虑一般情况下,try,catch,finally与return的执行。

如果执行到第二个return(比如try里面的return后执行finally里面的return),那么在栈空间分配的那块内存的内容会被替换成新的return后面的表达式的计算值。

即 try 有返回值 catch 有返回值 final 有返回值 应该如何处理

1. 返回值是基本数据类型。

    public int method(){
        int i = 0;
        try {
            return i;
        }catch (Exception e){
            
        }finally {
            i = 2;
            System.out.println(2222);
        }
        return i+5;
    }

输出结果:
2222
0

用内存的观点其实很好解释,return i;语句其实是在栈里新开辟了一块空间,然后把i的值赋给了新开辟的空间,所以赋值完毕后,i的值怎么变不影响返回值。
因此 很好解释 执行顺序是 , try 执行 然后将 return i; 放入一个开辟的空间,然后没有错误不去执行catch ,再执行 finally 如果遇到return 就去返回新的对象 返回值 i的值,没有的话 就 返回 i 的值 ,因此后面对i 操作 对返回的没有影响。

2. 返回值是引用数据类型。

在这种情况下,返回的数据可以被return之外的语句影响。

    public StringBuffer method(){
        StringBuffer i = new StringBuffer("");
        try {
            return i;
        }catch (Exception e){

        }finally {
            i.append("1322131");
            System.out.println(2222);
        }
        return i;
    }
2222
1322131

用内存的观点也很好解释,return i;语句会新开辟一个空间,将i的值赋给新开辟的新开辟的空间。但是i是引用类型,如果对i指向的对象进行操作,那么也会影响到返回值,因为他们指向同一块内存空间。

总结:

1:函数执行到try里面的内容,一定会执行finally里面的语句块,除非try里面有类似System.exit()的方法。

2:函数执行到return不一定会直接返回(比如try和catch里面的),但一定会开辟一块当前方法体返回类型的空间,里面的值存的是return后面的表达式计算结果,该结果会被第二个return(finally里面的)覆盖。

3:如果finally 没有返回值,如果 返回值是基本类型,后序对返回值操作就没有影响,如果是引用数据类型(注意:引用地址不发生改变)后序 有操作就会有影响。例如:对于像 String就有不同的结果,因为String 不能增加 如果变化,就是开辟新的空间 ,因此返回就是原来的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值