- 正常执行流程:
try执行,遇到异常就跳到catch执行(以使得程序不会崩溃);
不管有没有异常catch,最后都执行finally
- 含return语句执行流程分析:
若try块中return 可达, return语句(如:return x=x+1;):
- 对x执行运算x=x+1 (若有运算)
- 复制一个变量x给try的return语句(按值复制:基本类型就是值本身,对象就是地址值)
- 但return语句并不马上返回,控制权转移到finally块中执行: (1)若finally中无return语句:finally执行完后,try块执行return语句返回之前复制的变量x(基本类型就是值本身,对象就是地址值)(所以:若x为基本类型,fianlly中改变x对最终return结果无效;若x为对象类型,按地址值传递可以改变x的最终return结果) (2)若finally中有return语句:执行后直接返回(即“覆盖try中return语句”:try中return语句不再返回)
若try中return 不可达(exception 在return前出现):
exception出现后控制权直接转到catch 块(即try中 exception之后的语句<包括return>不会执行),最后到finally块(catch到finally中流程与上面try到finally中流程相同)
- finally不执行的特殊情况:
- if you call System.exit() or
- if the JVM crashes first
- A return statement in the finally block is a bad idea:
By doing a return from the finally block, you suppress the exception entirely.(finally 中有return ,try,catch的 return throw都不会再被调用)
publicstaticint getANumber(){
try{
thrownewNoSuchFieldException();
} finally {
return43;
}
}
Running the method above will return a “43” and the exception in the try block will not be thrown. This is why it is considered to be a very bad idea to have a return statement inside the finally block.
例子解释:
执行流程
- If the return in the try block is reached, it transfers control to the finally block, and the function eventually returns normally (not a throw).
- If an exception occurs, but then the code reaches a return from the catch block, control is transferred to the finally block and the function eventually returns normally (not a throw).
- In your example, you have a return in the finally, and so regardless of what happens, the function will return 34, because finally has the final (if you will) word.
finally语句在try或catch中的return语句执行之后、return返回之前执行的
- 在try中含有return+基本类型情况:
publicclassFinallyTest1{
publicstaticvoid main(String[] args){
System.out.println(test1());
}
publicstaticint test1(){
int b =20;
try{
System.out.println("try block");
return b +=80;
}
catch(Exception e){
System.out.println("catch block");
}
finally {
System.out.println("finally block");
if(b >25){
System.out.println("b>25, b = "+ b);
}
}
return b;
}
}
运行结果:
try block
finally block
b>25, b =100
100
- 在catch中含有return+基本类型情况(分析跟在try中含有return情况一样):
publicclassTest{
publicstaticvoid main(String[] args){
System.out.println(test1());
}
publicstaticint test1(){
int b =20;
try{
int a =1/0;//触发异常
System.out.println("try block");//不会被执行
return b +=80;//不会被执行
}
catch(Exception e){
System.out.println("catch block");
return b +=180;//最后在此返回
}
finally {
System.out.println("finally block");
if(b >25){
System.out.println("b>25, b = "+ b);
}
}
// return b;
}
}
执行结果:
catch block
finally block
b>25, b =200
200
- 在try中含有return+对象类型情况:
publicclassTest{
publicstaticvoid main(String[] args){
System.out.println(getMap().get("KEY").toString());
}
publicstaticMap<String,String> getMap(){
Map<String,String>map=newHashMap<String,String>();
map.put("KEY","INIT");
try{
map.put("KEY","TRY");
returnmap;//return在控制权转移到finally前:复制了一个map对象的地址值(对象按地址值传递)
}
catch(Exception e){
map.put("KEY","CATCH");
}
finally {
map.put("KEY","FINALLY");//根据对象地址值修改对象内容(按地址值传递),因此会影响try中return返回的对象内容
map= null;//map为null即不再指向该对象,
-
// 但由于前面return复制了一个对象的引用(地址值),而对象是被分配在堆中的,只要有引用指向这个对象,系统就不会回收此对象,
所以此处map = null 并不会影响最后try中return返回对象内容 }
returnmap;
}
}
执行结果:
FINALLY
- 在catch中含有return+基本类型情况(分析跟在try中含有return情况一样):
publicclassTest{
publicstaticvoid main(String[] args){
System.out.println(getMap().get("KEY").toString());
}
publicstaticMap<String,String> getMap(){
Map<String,String>map=newHashMap<String,String>();
map.put("KEY","INIT");
try{
int a =1/0;//触发异常
map.put("KEY","TRY");//不会被执行
returnmap;//不会被执行
}
catch(Exception e){
map.put("KEY","CATCH");
returnmap;//return在控制权转移到finally前:复制了一个map对象的地址值(对象按地址值传递)
}
finally {
map.put("KEY","FINALLY");//根据对象地址值修改对象内容(按地址值传递),因此会影响catch中return返回的对象内容
map= null;//map为null即不再指向该对象,
// 但由于前面return复制了一个对象的引用(地址值),而对象是被分配在堆中的,只要有引用指向这个对象,系统就不会回收此对象,
// 所以此处map = null 并不会影响最后catch中return返回对象内容
}
// return map;
}
}
执行结果:
FINALLY
finally块中的return语句会覆盖try块中的return返回
publicclassTest{
publicstaticvoid main(String[] args){
System.out.println(test2());
}
publicstaticint test2(){
int b =20;
try{
System.out.println("try block");
return b +=80;
}catch(Exception e){
System.out.println("catch block");
} finally {
System.out.println("finally block");
if(b >25){
System.out.println("b>25, b = "+ b);
}
return200;
}
// return b;
}
}
执行结果:
try block
finally block
b>25, b =100
200
参考:http://www.cnblogs.com/lanxuezaipiao/p/3440471.html(博文代码用例4结果有误,见该博文讨论区分析)