一、我们将try{}catch(){}finally{}分成以下几种情况分别验证:
场景1:try{return;}catch{}finally{} return;
public static int returnSttat(int i) {
System.out.println("return block");
return i;
}
public static int test01() {
int i = 0;
try {
i = 1;
return returnSttat(i);
}catch (Exception e) {
} finally {
System.out.println("finally block01");
}
return 0;
}
执行结果如下:
return block
finally block01
1
执行步骤: a) 执行try{}部分(包括return表达式); b) 执行finally{}部分; c) 返回try{}中return表达式结果.
场景2:try{}catch{}finally{} return 有异常场景;
public static int returnSttat(int i) {
System.out.println("return block");
return i;
}
public static int test01() {
int i = 1;
int divid = 0;
try {
int n = i / divid;
} catch (Exception e) {
System.out.println("catch block");
return returnSttat(i);
} finally {
System.out.println("finally block");
}
return 0;
}
执行结果如下:
catch block
return block
finally block
1
执行顺序: a) 执行try块抛出异常;b)catch拦截了异常并执行处理逻辑; c) 执行try中return 表达式;d)执行finally块; e) 执行return表达式返回值
场景3: try{return;} catch{} finally{return;}
public static int returnSttat(int i) {
System.out.println("return block");
return i;
}
public static int test01() {
int i = 1;
try {
System.out.println("try block");
return returnSttat(i);
} catch (Exception e) {
System.out.println("catch block");
}finally {
System.out.println("finally block");
return returnSttat(0);
}
}
执行结果如下:
try block
return block
finally block
return block
0
执行顺序: a) 执行try块,并执行其中return表达式; b) 执行finally块; c) 执行finally中return 表达式;d) 返回finally中return表达式结果(PS:由于finally中有return语句则直接返回退出)
场景4:try{return;} catch{} finally{return;}有异常
public static int returnSttat(int i) {
System.out.println("return block" + i);
return i;
}
public static int test01() {
int i = 1;
int j = 0;
try {
System.out.println("try block");
int k = i / j;
return returnSttat(i);
} catch (Exception e) {
System.out.println("catch block");
return returnSttat(-1);
}finally {
System.out.println("finally block");
return returnSttat(0);
}
}
执行结果:
try block
catch block
return block-1
finally block
return block0
0
执行顺序: a) 执行try块,并抛出异常; b) catch获取异常,执行其中语句,并执行其中return语句;c) 执行finally块中语句并执行return语句;d)返回finally语句中return结果集(由于finally中有return则直接返回退出)
场景5: try{}finally{}中引用类型对象发生修改
public static User test01() {
User user = new User("kk");
try{
System.out.println("try block: " + user);
return user;
} finally {
System.out.println("finally block: " + user);
user.name = "jj";
}
}
static class User {
String name;
User(String name) {
this.name = name;
}
@Override
public String toString() {
return hashCode() + ":"+ name;
}
}
执行结果:
try block: 780376:kk
finally block: 780376:kk
780376:jj
执行步骤: a) 执行try{}中块并执行return user语句;b)执行finally语句修改了u的属性name;c)返回u。(PS user属性竟然发生改变啦!)
场景6: try{}finally{}中引用类型对象返回
public static User test01() {
User user = new User("kk");
try{
System.out.println("try block: " + user);
return user;
} finally {
user = new User("jj");
return user;
}
}
static class User {
String name;
User(String name) {
this.name = name;
}
@Override
public String toString() {
return hashCode() + ":"+ name;
}
}
执行结果:
try block: 780376:kk
29092282:jj
执行步骤 : 与场景3同
二、总结
1. 在try中return,在finally执行前会把结果保存起来,即使在finally中有修改也以try中保存的值为准,但如果是引用类型,修改的属性会以finally修改后的为准;
2. 如果try/finally都有return,直接返回finally中的return。
3. 不管try,finally都会执行;
4. 永远不要在finally块中使用return(PS: 提醒自己)
三、参考链接:
1. java中关于try、catch、finally的总结
2. Java趣味分享:try/finally