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 {測試類Test:
private Source parent;
private String id;
private String name;
private List<Source> children;
public Source(String n){
this.id = n;
}
}
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代碼,編譯器會給出警告的,應該加以重視。
false
1
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。