1

问题描述

笔试

这是京东校招的笔试题:

clipboard.png

运行

clipboard.png

打印运行结果,就是3

clipboard.png

clipboard.png

clipboard.png

分析

我们将returnfinally拆为几种情况综合分析。

finally之后return

private static int func() {
    int a = 1;
    try {
        System.out.println("try");
        return a;
    } catch (Exception e) {
        System.out.println("catch");
    } finally {
        System.out.println("finally");
    }
    System.out.println("afterFinally");
    return 10;
}

clipboard.png

看执行结果,我们分析return的原理。

try中执行到return时,先把这个值存起来,再开辟一块内存存这个值,然后去执行finallyfinally执行之后,回去执行之前没执行完的return语句,将值返回。所以这种情况下,finally后的代码块是不执行的。

finally中return

private static int func() {
    int a;
    try {
        System.out.println("try");
        a = 1;
        return a;
    } catch (Exception e) {
        System.out.println("catch");
        a = 2;
        return a;
    } finally {
        System.out.println("finally");
        a = 3;
        return a;
    }
}

这就和笔试题中一样了。

clipboard.png

tryreturn,然后去执行finally,发现finally中也有return,然后就执行的是finally中的return,返回值为3

finally中改变变量的值

基本数据类型

将上一个例子中finally中的return a;删了,就是我们接下来的测试。我们看看finally中对变量的改变对返回值有没有影响。

private static int func() {
    int a;
    try {
        System.out.println("try");
        a = 1;
        return a;
    } catch (Exception e) {
        System.out.println("catch");
        a = 2;
        return a;
    } finally {
        System.out.println("finally");
        a = 3;
    }
}

clipboard.png

trya = 1;

clipboard.png

clipboard.png

tryreturn a;

clipboard.png

clipboard.png

finallya = 3;

clipboard.png

clipboard.png

这里虽然执行了a = 3,但是改变的是a的值,并没有改变返回值。

要是不信我们在finally再添加一行输出以验证我们的猜想。

clipboard.png

clipboard.png

引用数据类型

相信这里我分为两个类别来叙述,熟悉Java的你应该明白我接下来要说什么了。

clipboard.png

建个类MyObject,这里是为了演示方便才将value设置为public的,不要效仿啊。

public static void main(String[] args) {
    MyObject object = func();
    System.out.println(object.value);
}

private static MyObject func() {
    MyObject myObject = new MyObject();
    try {
        System.out.println("try");
        myObject.value = 1;
        return myObject;
    } catch (Exception e) {
        System.out.println("catch");
        myObject.value = 2;
        return myObject;
    } finally {
        System.out.println("finally");
        myObject.value = 3;
    }
}

与之前类似,不过这里是在finally中修改对象的属性。

clipboard.png

运行,返回的结果是我们在finally中改变过的值。

clipboard.png

finally中改变的,是myObject这个对象的value值,这个对象在堆内存中,而栈内存中用于返回的对象,其实也是堆内存中对象的引用,所以finally的改变会改变引用数据类型的返回值。

总结

格物致知,这是对基础的最佳实践。

张喜硕
2.1k 声望423 粉丝

浅梦辄止,书墨未浓。