测试用例:
@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。