java基础-finally块对return变量的影响分析

来源:互联网 发布:创维网络机顶盒e900 编辑:程序博客网 时间:2024/06/04 18:02

          java语句的try-catch-finally执行过程中,finally语句块中如果操作了return语句的变量,它对方法的返回值是没有影响的,通过javap分析生成的字节码可以知道,在正常代码块执行完成后,会将需要返回的值存储到单独的局部变量中,而finally操作的局部变量仍然是返回值最初存入的局部变量。由于返回值做了备份,finally对原局部变量的重定向(如果是引用类型),或者修改(基础类型),不会对方法的返回值产生影响。

         finally语句会在return语句之前执行,是因为java文件编译过程中已经对try-catch-finally语句做了处理:编译后方法的出口有三种,第一种是正常的try分支,它的字节码内容是java代码中try的语句加上finally的语句;第二种是catch分支,内容=java代码的catch语句+finally语句;第三种是其他异常,内容=finally语句+athrow。

         简单类Source源码:

public class Source {private Source parent;private String id;private String name;private List<Source> children;public Source(String n){this.id = n;}}
          测试类Test:
public class Test {public static void main(String[] args) {Source c = get();System.out.println(c ==null);System.out.println(c.getId());}public static Source get(){Source source =null;try{source = new Source("1");return source;}catch (IndexOutOfBoundsException e){return null;}finally{source = new Source("2");}}}
           javap -c Test命令查看字节码内容,分析如下:


            从字节码看,就很容易明白为什么finally语句并不能对返回值造成影响了。Test语句的执行结果如下,finally虽然对source重新new了,但是作为返回值的source引用已经被备份到了1号局部变量了,所以返回值的引用地址是固定的,同时catch分支也是一样。因为finally语句是每个语句块中最后一部分执行的,所以在finally写return语句有出错的风险,finally里面的return必定会改变正常分支中的返回值。所以在finally中写入return代码,编译器会给出警告的,应该加以重视。

false1

0 0
原创粉丝点击