Java代码中的try ..finally返回值问题

版权声明:知识共享 https://blog.csdn.net/liyaowen505/article/details/84257573

首先明确一点,finally 块中的 return 返回后方法结束执行,不会再执行 try 块中的 return 语句。
那么如果finally修改某个变量会影响try中的返回值吗?代码如下:

private static Map<String, String> finallyTestByMap() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("KEY", "INIT");
    try {
        map.put("KEY", "TRY");
        return map;
    } catch (Exception e) {
        map.put("KEY", "CATCH");
    } finally {
        map.put("KEY", "FINALLY");
        map = null;  //不管用
    }
    return map;
}

此map.get(“KEY”)的结果为FINALLY。

private static Integer finallyTestByInt() {
    Integer a= 1;
//        int a = 1;
        try {
            a = 2;
            return a;
        } catch (Exception e) {
            a= 3;
        } finally {
            a = 4;
        }
        return a;
    }

此a 的返回值为2。

private static String finallyTestByString() {
    String a = "init";
    try {
        a = "try";
        return a;
    } catch (Exception e) {
        a= "catch";
    } finally {
        a = "finally";
    }
    return a;
}

此 a 的返回值为try。

private static List<String> finallyTestByList() {
    List<String> a = new ArrayList<>(1);
    try {
        a.add("try");
        return a;
    } catch (Exception e) {
        a.add("catch");
    } finally {
        a.set(0, "finally");
        a= null;
    }
    return a;
}

此 a 的返回值为finally。

此前在网上查了很多,基本就分为基本类型和引用类型的区别。
如果是基本类型,finally块的操作不会改变try块中的;引用类型则会受影响。
现在来看下编译后的代码。

private static Map<String, String> finallyTestByMap() {
        Map<String, String> map = new HashMap();
        map.put("KEY", "INIT");
    try {
        map.put("KEY", "TRY");
        HashMap var1 = map;
        return var1;
    } catch (Exception var5) {
        map.put("KEY", "CATCH");
    } finally {
        map.put("KEY", "FINALLY");
        map = null;
    }

    return map;
}

private static Integer finallyTestByInt() {
    Integer a = 1;

    try {
        a = 2;
        Integer var1 = a;
        return var1;
    } catch (Exception var5) {
        a = 3;
    } finally {
        a = 4;
    }

    return a;
}

private static String finallyTestByString() {
    String a = "init";

    try {
        a = "try";
        String var1 = a;
        return var1;
    } catch (Exception var5) {
        a = "catch";
    } finally {
        a = "finally";
    }

    return a;
}

private static List<String> finallyTestByList() {
    ArrayList a = new ArrayList(1);

    try {
        a.add("try");
        ArrayList var1 = a;
        return var1;
    } catch (Exception var5) {
        a.add("catch");
    } finally {
        a.set(0, "finally");
        a = null;
    }

    return a;
}

仔细看下try中的不同,原来jvm在try中又新建了一个副本,现在看来就明白了原因。
其实按照引用类型和基本类型区分感觉有点不妥,String也是引用类型,但表现了基本类型的结果。
其实说到底可以归为赋值的问题,引用也是对不同地址的赋值,只要进行的是赋值操作,finally的操作就不会影响try中的副本,就像你和我指向同一个篮子,篮子中有一个苹果,你是副本,就算我挂了篮子还在,并没有直接操作篮子,篮子中还是一个苹果;
只有finally和try操作的是同一个对象本身,比如类似map和list这种,操作的是篮子,才会互相影响。

猜你喜欢

转载自blog.csdn.net/liyaowen505/article/details/84257573