結論:
一、無論有沒有出現異常,finally塊中代碼都會執行;
二、當try和catch中有return時,finally仍然會執行;
三、finally是在return後面的表達式運算後執行的(此時並無返回運算後的值,而是先把要返回的值保存起來,無論finally中的代碼怎麼樣,返回的值都不會改變,任然是以前保存的值),因此函數返回值是在finally執行前肯定的;
四、finally中最好不要包含return,不然程序會提早退出,返回值不是try或catch中保存的返回值。
舉例:
狀況1:try{} catch(){}finally{} return;
顯然程序按順序執行。
狀況2:try{ return; }catch(){} finally{} return;
程序執行try塊中return以前(包括return語句中的表達式運算)代碼;
再執行finally塊,最後執行try中return;
finally塊以後的語句return,由於程序在try中已經return因此再也不執行。
狀況3:try{ } catch(){return;} finally{} return;
程序先執行try,若是遇到異常執行catch塊,
有異常:則執行catch中return以前(包括return語句中的表達式運算)代碼,再執行finally語句中所有代碼,
最後執行catch塊中return. finally以後也就是4處的代碼再也不執行。
無異常:執行完try再finally再return.
狀況4:try{ return; }catch(){} finally{return;}
程序執行try塊中return以前(包括return語句中的表達式運算)代碼;
再執行finally塊,由於finally塊中有return因此提早退出。
狀況5:try{} catch(){return;}finally{return;}
程序執行catch塊中return以前(包括return語句中的表達式運算)代碼;
再執行finally塊,由於finally塊中有return因此提早退出。
狀況6:try{ return;}catch(){return;} finally{return;}
程序執行try塊中return以前(包括return語句中的表達式運算)代碼;
有異常:執行catch塊中return以前(包括return語句中的表達式運算)代碼;
則再執行finally塊,由於finally塊中有return因此提早退出。
無異常:則再執行finally塊,由於finally塊中有return因此提早退出。
最終結論:任何執行try 或者catch中的return語句以前,都會先執行finally語句,若是finally存在的話。
若是finally中有return語句,那麼程序就return了,因此finally中的return是必定會被return的,
編譯器把finally中的return實現爲一個warning。app
(一) 通常狀況下,程序執行到try裏面的內容必定會執行finally裏面的內容。若是在try或者catch裏面遇到return,那麼函數在執行完return後面的表達式以後,會先去執行finally裏面的語句塊,而後再結束方法體。但有一種特殊狀況,若是在try裏面有System.exit(0)這樣的語句,System.exit(0)是終止Java虛擬機JVM的,連JVM都中止了,全部都結束了,固然finally語句也不會被執行到。如今考慮通常狀況下,try,catch,finally與return的執行。函數
(二) 討論返回值的類型spa
1.返回值是基本數據類型。code
在這種狀況下,返回的數據不會被return以外的語句影響。對象
例子:blog
public class Test { public static void main(String[] args) { System.out.println("main:" + getI() ); } public static int getI() { int i = 1; try { i++; System.out.println("try:" + i); throw new FileNotFoundException(); } catch (Exception e) { i+=2; System.out.println("catch:" + i); return i; } finally { i+=3; System.out.println("finally:" + i); } } } 結果: try:2 catch:4 finally:7 main:4
2.返回值是引用數據類型。get
在這種狀況下,返回的數據能夠被return以外的語句影響。編譯器
例子:虛擬機
public class Test { public static void main(String[] args) { System.out.println("main:" + getStr() ); } public static StringBuffer getStr() { StringBuffer str = new StringBuffer("ab"); try { str.append("try"); System.out.println("try:" + str); throw new FileNotFoundException(); } catch (Exception e) { str.append("catch"); System.out.println("catch:" + str); return str; } finally { str.append("finally"); System.out.println("finally:" + str); } } } 結果: try:abtry catch:abtrycatch finally:abtrycatchfinally main:abtrycatchfinally
3.返回是對象類型
it
public static void main(String[] args) { System.out.println("main:" + getPerson() ); } public static String getPerson() { Person person = new Person(); try { person.setName("小明"); System.out.println("try:" + person); throw new FileNotFoundException(); } catch( Exception e ) { person.setSex('男'); System.out.println("catch:" + person); return person.toString(); } finally { person.setAge(24); System.out.println("finally:" + person); } } }
結果: