1、不管有没有异常,finally中的代码都会执行
2、当try、catch中有return时,finally中的代码依然会继续执行
3、finally是在return后面的表达式运算之后执行的,如果是返回基本类型的值,此时并没有返回运算之后的值,而是把值保存起来,不管finally对该值做任何的改变,返回的值都不会改变,依然返回保存起来的值。也就是说方法的返回值是在finally运算之前就确定了的。
4、如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。
5、finally代码中最好不要包含return,程序会提前退出,也就是说返回的值不是try或catch中的值
package test;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static List<String> test1() {
List<String> list = new ArrayList<>();
try {
list.add("a");
return list;
} finally {
list = new ArrayList<>();
list.add("b");
}
}
// 结果返回:[a]
/**********************************************/
public static List<String> test2() {
List<String> list = new ArrayList<>();
try {
list.add("a");
return list;
} finally {
list.add("b");
}
}
// 结果返回:[a,b]
/**********************************************/
public static Car test3() {
Car car = new Car();
try {
car.setSize(1);
return car;
} finally {
car = new Car();
car.setSize(2);
}
}
// 结果返回:car [size=1]
/**********************************************/
public static Car test4() {
Car car = new Car();
try {
car.setSize(1);
return car;
} finally {
car.setSize(2);
}
}
// 结果返回:car [size=2]
/**********************************************/
public static int test5() {
int i = 0;
try {
i = 1;
return i;
} finally {
i = 2;
}
}
// 结果返回:1
/**********************************************/
public static int test6() {
int i = 0;
try {
throw new RuntimeException();
} catch (Exception e) {
i = 1;
return i;
} finally {
i = 2;
}
}
// 结果返回:1
/**********************************************/
public static Car test7() {
Car car = new Car();
try {
throw new RuntimeException();
} catch (Exception e) {
car.setSize(1);
return car;
} finally {
car.setSize(2);
}
}
// 结果返回:car [size=2]
/**********************************************/
public static void main(String[] args) {
System.out.println("-------在try块中返回-------");
System.out.println(test1());
System.out.println(test2());
System.out.println(test3());
System.out.println(test4());
System.out.println(test5());
System.out.println("-------在catch块中返回-------");
System.out.println(test6());
System.out.println(test7());
}
}
class Car {
private int size;
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
@Override
public String toString() {
return "car [size=" + size + "]";
}
}
private static String test1(){
String a = "xxx";
try{
return a;
}
finally{
a+="yyy";
System.out.println("test1 finally running, a = " + a);
}
}
private static StringBuffer test2(){
StringBuffer a = new StringBuffer("xxx");
try{
return a;
}
finally{
a.append("yyy");
System.out.println("test2 finally running, a = " + a);
}
}
public static void main(String[] args) {
System.out.println("test1 main running return a is "+test1());
System.out.println("test2 main running return a is "+test2());
}
/* 运行结果:
test1 finally running, a = xxxyyy
test1 main running return a is xxx
test2 finally running, a = xxxyyy
test2 main running return a is xxxyyy
*/
String虽然是引用类型的对象,但是String类有final关键字进行修饰的类(让它具有了基本数据类型的属性)。也就是说String是常量对象,不可更改,不同的字符串就是不同的对象。
在try中return的字符串是“xxx”,这是假设有个临时引用temp指向了“xxx”字符串。但是到了finally代码块中,a+=“yyy”,新生成了“xxxyyy”字符串,属于一个新的String对象。即try中引用a和finaly中的引用a指向的对象不是同一个了!
所以返回到main函数中的是temp指向的xxx,而在finally中输出的是a新指向的xxxyyy。
参考博客:https://blog.csdn.net/maijia0754/article/details/78474823
http://www.mamicode.com/info-detail-2875638.html
https://blog.csdn.net/BaiDingLT/article/details/71179750