try catch finally 中的 finally 和 return

测试用例:

@Test
    public void test03(){
        System.out.println(tryCatchPrimitive());

        System.out.println(tryCatchReference());
    }

    private int tryCatchPrimitive(){
        int primitiveType = 0;
        try {
            primitiveType = 1;
            return primitiveType;
        } finally {
            primitiveType = 2;
        }
    }

    private Map<String, String> tryCatchReference(){
        Map<String, String> referenceType = new HashMap<>();
        referenceType.put("key", "init");
        try {
            referenceType.put("key", "try");
            return referenceType;
        } finally {
            referenceType.put("key", "finally");
            referenceType = null;
        }
    }

输出结果:

1
{key=finally}

分析

  • try catch finally 块中 try 与 finally 的关系和 catch(如果 catch 被执行到的话) 与 finally 的关系一样。

  • try finally return 要分析两种情况,一种是 return 基本数据类型,另一种是 return 引用类型。

  • try 和 catch 中的 return 是在 finally 执行之前执行,在 finally 执行之后返回。

第一个测试案例中 try 返回 变量 primitiveType,finally 修改了 primitiveType 的值,但是返回的到的值是 1,说明 finally 对 primitiveType 的修改没有生效。说明修改 primitiveType 并没有修改方法返回的值,因为方法将计算得到的返回值复制了一份保存起来,所以修改 primitiveType 的值并不会修改被保存起来的返回值。

在第二个案例中 try 返回变量 referenceType,finally 修改了 referenceType 中键为 key 的值,并将 referenceType 赋值为 null,方法返回的结果并不会 null,却键为 key 的值为 finally,说明 finally 块中对 referenceType 的修改影响了方法的返回值。这和案例一相悖。这是因为案例二的返回值是引用类型,对于引用类型方法保存的返回值是引用的地址,我们不妨将方法保存的变量叫 returnType,那么 returnType 和 referenceType 指向同一个 Map 对象,所以 referenceType 的修改会反应到 returnType 上,但是将 referenceType = null 并不会修改 returnType,所以返回的 Map 对象不是 null。

你可能感兴趣的:(java,jvm,开发语言)