try...catch...finally与返回值的问题

面试过程中,面试官经常会问一下代码细节的问题,比如在try...catch...finally都有return语句,那么那个代码块中的return会生效呢?又比如在try中返回一个值a,finally中修改这个值,那么返回的a是finally中修改过的还是没有修改过的呢?下面我们通过几组案例来分析下有关try...catch...finally中返回值的问题。

注意:无论发生什么情况,finally中的语句是一定会执行的

案例1:try代码块中发生异常时候,哪个部分的return会执行呢?

测试代码

public class TryCatchDemo {
    public static void main(String[] args) {
        System.out.println(tryCatchTest());
    }

    public static int tryCatchTest() {
        try {
            //制造异常,设置return语句
            int a = 3/0;
            return 1;
        }catch (Exception e) {
            //捕捉异常,并在catch设置了return语句
            System.out.println("捕捉的异常了");
            return 2;
        }finally {
            //在finally中设置返回语句
            System.out.println("finally执行了");
            return 3;
        }
    }
}

运行结果

结果分析

最后的返回值是finally中的return语句的值,在try中发生了异常之后,异常之后的语句就不会再执行了,也就是说try中的return语句没有执行,catch中虽然有return语句,但是finally中代码是一定会执行的,所以在catch中return语句执行前执行了finally中的语句,所以最后返回的是3。假设这里没有finally,那么返回的是2,也就是catch中的return

案例2:try中没有发生异常,哪个部分的return会执行呢?

测试代码

public class TryCatchDemo {
    public static void main(String[] args) {
        System.out.println(tryCatchTest());
    }

    public static int tryCatchTest() {
        try {
            //设置return语句
            return 1;
        }catch (Exception e) {
            //捕捉异常,并在catch设置了return语句
            System.out.println("捕捉的异常了");
            return 2;
        }finally {
            //在finally中设置返回语句
            System.out.println("finally执行了");
            return 3;
        }
    }
}

运行结果

结果分析

返回的结果依然是finally中的值,finally中的语句是一定会执行的,所以在try中的return语句执行之前,去执行了finally中的语句,而fianlly中有return语句,所以最后返回的是3。

案例3:设置一个基本类型的变量,finally中修改该变量的值,try中返回该变量,那么最终返回的变量的值是多少呢?

测试代码

public class TryCatchDemo {
    public static void main(String[] args) {
        System.out.println(tryCatchTest());
    }

    public static int tryCatchTest() {
        //设置返回值
        int a = 1;
        try {
            return a;
        }finally {
            //改变返回值
            System.out.println("finally执行了");
            a = 3;
        }
    }
}

运行结果

结果分析

虽然在finally中a=3修改了a的值,但是最后依然返回的是1,说明try中在return之前将返回值保存了起来,finally中的修改并没有生效。

案例4:设置一个引用类型的变量,finally中修改该变量的值,try中返回该变量,那么最终返回的变量的值是多少呢?

测试代码

public class TryCatchDemo {
    public static void main(String[] args) {
        System.out.println(tryCatchTest().getName());
    }

    public static Child tryCatchTest() {
        //创建对象实例并设置初始name
        Child child = new Child("张三");
        try {
            return child;
        }finally {
            //修改对象中的name
            System.out.println("finally执行了");
            child.setName("李四");
        }
    }
}
//设置又给对象
class Child {
    private String name;
    public Child(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

运行结果

结果分析

因为变量是引用数据类型,变量相当于是对象的地址,在finally中的修改实际上修改了对象中的值,所以对于引用数据类型,finally中的修改会生效。

总结

  • finally中的语句是一定会执行的,所以如果finally中有return语句,那么程序会在finally中返回
  • 如果finally中没有return语句,执行完finally会去执行try或者catch中的return,如果没发生异常,则执行try中的return,如果发生了异常,那么执行catch中的return
  • 对于基本类型或者字符串,在finally中的修改并不起作用,try中的return返回值仍然是再进入finally之前保存的值。
  • 对于引用类型的数据,在finally中的修改会起作用,try中return返回值是finally修改后的值。
posted @ 2020-07-26 20:35  un1que~  阅读(554)  评论(0编辑  收藏  举报