finally和return的执行顺序/在finally块中修改变量值的影响

南楼画角 提交于 2020-03-11 12:10:23

1、try块中有return时,finally块依旧可以执行

public static int test1() {
    try {
       return 1;
    } finally {
       System.out.println("try中有return时,finally块依旧可以执行,且在return之前执行");
    }
}

执行结果:

2、catch块中有return时,finally依旧可以执行

public static int test2() {

   try {
     //此处制造异常
      int a = 1 / 0;
      return 1;
    } catch (Exception e) {
        return 2;
    } finally {
       System.out.println("catch中有return时,finally块依旧可以执行,且在return之前执行");
    }
}

执行结果:

3、finally中也有return时,会直接返回,此时忽略try/catch中的return

public static int test3() {

   try {
      //此处制造异常
      int a = 1 / 0;
      return 1;
   } catch (Exception e) {
      return 2;
   } finally {
      System.out.println("执行finally的return");
      return 3;
   }
}

执行结果:

4、finally中修改返回的变量(基本数据类型)

public static int test4() {

        int i = 0;
        try {
            i = 1;
            return i;
        } finally {
            System.out.println("在finally块中修改i的值为3");
            i = 3;
        }
}

执行结果:

5、在catch块中修改返回变量值(基本数据类型)

public static int test5() {

        int i = 0;
        try {
            i = 1;
            //此处制造异常
            int a = 1 / 0;
            return i;
        } catch (RuntimeException e) {
            System.out.println("在finally块中修改i的值为2");
            i = 2;
            return i;
        } finally {
            System.out.println("在finally块中修改i的值为3");
            i = 3;
        }
}

执行结果:

6、finally中修改返回引用类型的属性值(引用类型:自定义的Person类)

@Data
@ToString
@AllArgsConstructor
public class Person {

    /**
     * 
     * 使用了lombok注解
     * @ToString 自动重写toString方法
     * @Data  自动写属性的getter和setter方法
     * @AllArgsConstructor 创建包含所有参数的构造函数
     * */

    private String name;

    private int age;

}

创建一个person对象传参调用:

  
public static void main(String[] args) {

        Person person = new Person("精神小伙", 18);
        System.out.println(test6(person));
}

public static Person test6(Person person) {
        try {
            person.setAge(20);
            person.setName("精神不起来");
            return person;
        } finally {
            System.out.println("在finally块中修改person属性值");
            person.setAge(18);
            person.setName("精神小伙");
        }
}

执行结果:此时修改的是引用变量的属性,而不是引用变量自身。

7、finally中修改返回的引用类型变量(引用类型:自定义的Person类)

 public static Person test7(Person person) {
        try {
            person.setAge(20);
            person.setName("精神不起来");
            return person;
        } finally {
            System.out.println("在finally块中修改person引用");
            person = new Person("精神小伙", 18);
        }
}

执行结果:此时修改的是引用变量

8、在finally中修改返回变量(String)

    public static String test8() {
        String s = "";
        try {
            s = "string";
            return s;
        } finally {
            //return时已经记录s的地址,
            //当前操作为将s指向别的地址,故对返回值无关
            s = "update string";
            System.out.println("在finally块修改string值");
        }
    }

执行结果:

9、一道面试题

public class Test {

    private static String result = "";

    public static void main(String[] args) {
        test(1);
        //这句是我加的,方便分析流程
        result += "*";
        test(0);
        System.out.println(result);
    }

    public static void test(int i) {

        result += "1";
        try {
            if (i == 0) {
                throw new RuntimeException("");
            }
            result += "2";
        } catch (Exception e) {
            result += "3";
            //这里只是终止程序,不要看错了
            return;
        } finally {
            result += "4";
        }
        result += "5";
    }
}

执行结果:

分析:test()方法没有返回值,所以在所有的try/catch/finally之后底下的语句也要执行!!!有时候上面的返回值看久了,一直觉得要返回,自己把底下的语句忽略了。

第一次执行:不抛出异常,所以除了catch中的语句不执行,其他都执行;则得出结果result = 1245

第二次执行:此时的result = 1245*;这次抛出异常,result+=2语句在抛出异常之后,所以不会执行;并且在catch块中赋值语句执行完之后,终止程序。所以,最后的result+="5"不会执行;最后可以得出最终的结果是1245*134

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!