有return的情况下try catch finally的执行顺序

前言,在写java 异常捕捉块的时候,有时候用到return,有时有各种情况,不仔细分析的化就会出现意想不到的问题,所以我测试一般情形,用于记录一下。

情景1:try{}catch{}finally{}return 在这种情况下代码顺序执行

如:

 

package ming;

public class Testt {

    public static int a() throws Exception{
        int a=0;
        try {
            System.out.println(1/0);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            a=9;
        }
        return a;
    }
    
  //即使出现了异常,代码从上往下执行...不含糊
public static void main(String[] args) throws Exception{ int a = a(); System.out.println(a);// 返回值为9 } }

情景2:try{}catch{throw e;}finally{}return 如果在catch这个块把异常抛出去,此时你不能获取返回值。

如:

package ming;

public class Testt {

    public static int a() throws Exception {
        int a = 0;
        try {
            System.out.println(1 / 0);
        } catch (Exception e) {
            throw new Exception(e);
        } finally {
            a = 9;
        }
        return a;
    }

    public static void main(String[] args) throws Exception {
        int a = a();
        System.out.println(a);//此时没有什么答案,仅仅抛出了一个异常而已,代码依然是从上往下执行

    }

}

情景3:try{return}catch{}finally{}return 这样的结构其实最后的return 只是为了防止try语块没有返回值,如果try有返回值,最后finally 大括号后面的代码不会执行的。

执行流程也是从上往下,只是遇到了return 了,代码去执行finally的,然后返回try执行,最后finally后面的代码就不会去执行了,因为有返回值了。

如:

package ming;

public class Testt {

    public static int a() throws Exception {
        int a = 0;
        try {
            a=1;
            return a;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            a = 9;
        }
        a=10;//这代码是没有执行的
        return a;
    }

    public static void main(String[] args) throws Exception {
        int a = a();
        System.out.println(a);//输出1

    }

}

情景4:try{return}catch{throw}finally{} 在返回值之前抛出异常,显然最后没有什么结果了

如:

package ming;

public class Testt {

    public static int a() throws Exception {
        int a = 0;
        try {
            a=1;
            System.out.println(1/0);
            return a;
        } catch (Exception e) {
            throw  new Exception(e);
        } finally {
            a = 9;
        }
    }

    public static void main(String[] args) throws Exception {
        int a = a();
        System.out.println(a);

    }

}

情景4:try{return}catch{throw}finally{return} 在返回值之前抛出异常,finally 有return情况下,最后显然返回finally return的值了。

如:

package ming;

public class Testt {

    public static int a() throws Exception {
        int a = 0;
        try {
            a=1;
            System.out.println(1/0);
            return a;
        } catch (Exception e) {
            throw  new Exception(e);
        } finally {
            a = 9;
            return a;
        }
    }

    public static void main(String[] args) throws Exception {
        int a = a();
        System.out.println(a);//返回值为9

    }

}

情景5:try{return}catch{return}finally{return} 依然以finally最后的return 作为返回值

如:

package ming;

public class Testt {

    public static int a() throws Exception {
        int a = 0;
        try {
            a=1;
            System.out.println(1/0);
            return a;
        } catch (Exception e) {
            a=10;
            return a;
        } finally {
            a = 9;
            return a;
            
        }
    }

    public static void main(String[] args) throws Exception {
        int a = a();
        System.out.println(a);//返回值为9

    }

}

情景6:try{return}catch{return}finally{} 如果try中异常返回catch中返回值,否则返回try中的

如:

package ming;

public class Testt {

    public static int a() throws Exception {
        int a = 0;
        try {
            a=1;
            System.out.println(1/0);
            return a;
        } catch (Exception e) {
            a=10;
            return a;
        } finally {
            a = 9;
        }
    }

    public static void main(String[] args) throws Exception {
        int a = a();
        System.out.println(a);//返回10

    }

}

情景7:我们把返回值类型改为对象类型测试一下:此时跟基本类型不一样,这是因为java 是值传递而不是引用传递

如:

package ming;

public class Testt {

    public static Stu a() throws Exception {
        Stu stu=new Stu();
        try {
            stu.setName("张三");;
            return stu;
        } catch (Exception e) {
            
        } finally {
            stu.setName("李四");;
        }
        return stu;
    }

    
    
    public static void main(String[] args) throws Exception {
        Stu stu = a();
        System.out.println(stu.getName());//此时返回李四

    }

}

class Stu{
    
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

总结一下:

1.不管有木有出现异常,finally块中代码都会执行;
2.当try和catch中有return时,finally仍然会执行,执行是try,如果有异常就执行catch,最后依然执行finally,即使有return,代码先忽视return,从上往下执行,然后返回代码try 或catch中的return。如果fianlly有return ,代码就不会执行try 或catch的return。

3.finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

4.如果catch中抛出异常,你不会得到你的返回值。这在设计程序的时候要注意这个问题。

5. finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中 return已经确定的返回值

可能影响也可能不影响指的是:因为java 是值传递而不是引用传递

参考:https://my.oschina.net/huluerwa/blog/311328

原文地址:https://www.cnblogs.com/huzi007/p/6611132.html