版权声明:知识共享 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这种,操作的是篮子,才会互相影响。