关于finally的几个问题

来源:互联网 发布:java常用设计模式详解 编辑:程序博客网 时间:2024/05/20 10:51

 

1、Finally块中代码在什么时候执行?

package testfinally;public class Test {public static int test(){try{return 1;}catch(Exception e){return 0;}finally{System.out.println("execute finally");}}public static void main(String[] args) {// TODO Auto-generated method stubint result = test();System.out.println(result);}}
结果输出:1

package testfinally;public class Test {public static int test(){try{throw new Exception();}catch(Exception e){return 2;}finally{System.out.println("execute finally");}}public static void main(String[] args) {// TODO Auto-generated method stubint result = test();System.out.println(result);}}
结果输出:2

结果分析:finally块中代码在相应的try..catch块中执行return语句前执行。

2、finallyreturn语句覆盖try..catch中的return?

package testfinally;public class Test {public static int test(){try{return 1;}catch(Exception e){return 2;}finally{System.out.println("execute finally");return 3;}}public static void main(String[] args) {// TODO Auto-generated method stubint result = test();System.out.println(result);}}
结果输出:3

package testfinally;public class Test {public static int test(){try{throw new Exception();}catch(Exception e){return 2;}finally{System.out.println("execute finally");return 3;}}public static void main(String[] args) {// TODO Auto-generated method stubint result = test();System.out.println(result);}}
结果输出:3

结果分析:finallyreturn语句覆盖try..catch中的return,直接在finally返回。

3、finally里的返回基本类型和引用型对象的问题

package testfinally;public class Test {public static int test(){int result = 0;try{result = 1;return result;}catch(Exception e){result = 2;return result;}finally{result = 3;System.out.println("execute finally");}}public static String test2(){String result;try{result = new String("aaa");return result;}catch(Exception e){result =  new String("bbb");return result;}finally{result =  new String("ccc");System.out.println("execute2 finally");}}public static StringBuffer test3(){StringBuffer result = new StringBuffer("hello");try{return result;}catch(Exception e){return null;}finally{result.append(" world");System.out.println("execute3 finally");}}public static Person test4(){Person p1 = new Person(11,"张三");try{return p1;}catch(Exception e){return null;}finally{p1.setAge(12);p1.setName("李四");System.out.println("execute4 finally");}}public static void main(String[] args) {// TODO Auto-generated method stubint result = test();System.out.println(result);String result2 = test2();System.out.println(result2);StringBuffer result3 = test3();System.out.println(result3.toString());Person result4 = test4();System.out.println(result4.toString());}}

结果输出:

1
execute2 finally
aaa
execute3 finally
hello world
execute4 finally
name: 李四;age: 12

分析结果:由于在一个方法内部定义的变量都存储在栈中,当这个函数结束后,其对应的栈就会被回收,此时在其方法体中定义的变量将不存在,因此return返回时不是直接返回变量的值,而是先产生一个副本暂存,最后返回该副本。因此对于基本类型的数据,在finally块中改变return的值对返回的副本值没有任何影响。而对于引用型变量,当产生一个副本时,对于引用对象型数据并没有重新复制一份,而是指向了原来的数据,所以改变引用型中的对象数据,也就改变了副本中的引用型对象数据。对于test2的返回结果和test1一样是因为,引用型变量又指向了重新的定义的对象,而并为对其指向的对象型数据进行改变,所以没有引起副本中的对象型数据发生改变。


4、副本是在什么情况下产生的呢?

package testfinally;public class Test {public static int test(){int result = 0;try{result = 1;//return result;}catch(Exception e){result = 2;//return result;}finally{result = 3;System.out.println("execute finally");}return result;}public static void main(String[] args) {// TODO Auto-generated method stubint result = test();System.out.println(result);}}
输出结果:3

package testfinally;public class Test {public static int test(){int result = 0;try{result = 1;return result;}catch(Exception e){result = 2;//return result;}finally{result = 3;System.out.println("execute finally");}return result;}public static void main(String[] args) {// TODO Auto-generated method stubint result = test();System.out.println(result);}}

输出结果:1

结果分析:

所以我认为在有return语句的try或者catch语句块里创建副本




0 0
原创粉丝点击