Java程式碼中的try ..finally返回值問題
阿新 • • 發佈:2018-11-27
首先明確一點,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這種,操作的是籃子,才會互相影響。