一:2種finally不會執行的情況
a.在try語句之前就return了
b.try語句中有System.exit();語句
二:finally語句在return執行之后,return返回之前執行
例1:
public class FinallyTest1 { public static void main(String[] args) { test1(); } public static int 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; } }
console:
try block finally block b>25, b = 100
說明:在return b += 80;后先執行finally語句
再來一個例子加強這個事實
例2
public class FinallyTest1 { public static void main(String[] args) { System.out.println(test11()); } public static String test11() { try { System.out.println("try block"); return test12(); } finally { System.out.println("finally block"); } } public static String test12() { System.out.println("return statement"); return "after return"; } }
console:
try block return statement finally block after return
說明:先執行了return 語句中的方法,然后返回值
三:如果finally中有return語句呢?
public class FinallyTest1 { public static void main(String[] args) { System.out.println(test2()); } public static int 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); } return 200; } // return b; } }
console:
try block finally block b>25, b = 100 200
說明:finally里的return直接返回了,就不管try中是否還有返回語句,這里還有個小細節需要注意,finally里加上return過后,finally外面的return b就變成不可到達語句了,也就是永遠不能被執行到,所以需要注釋掉否則編譯器報錯。
四:如果finally語句中沒有return語句覆蓋返回值,那么原來的返回值可能因為finally里的修改而改變也可能不變。
public class FinallyTest1 { public static void main(String[] args) { System.out.println(test3()); } public static int test3() { 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); } b = 150; } return 2000; } }
console:
try block finally block b>25, b = 100 100
對比下面的這個程序
public class FinallyTest1 { public static void main(String[] args) { System.out.println(getMap().get("KEY").toString()); } public static Map<String, String> getMap() { Map<String, String> map = new HashMap<String, String>(); map.put("KEY", "INIT"); try { map.put("KEY", "TRY"); return map; } catch (Exception e) { map.put("KEY", "CATCH"); } finally { map.put("KEY", "FINALLY"); map = null; } return map; } }
console:
FINALLY
說明:為什么測試用例1中finally里的b = 150;並沒有起到作用而測試用例2中finally的map.put("KEY", "FINALLY");起了作用而map = null;卻沒起作用呢?這就是Java到底是傳值還是傳址的問題了
1.值傳遞不可以改變原變量的內容和地址;
2.引用傳遞不可以改變原變量的地址,但可以改變原變量的內容;
3.注意:String str = new String("good")特殊,因為String是個特殊的final類,所以每次對String的更改都會重新創建內存地址並存儲(也可能是在字符串常量池中創建內存地址並存入對應的字符串內容),但是因為這里String是作為參數傳遞的,在方法體內會產生新的字符串而不會對方法體外的字符串產生影響。相當於值傳遞
五:是不是每次返回的一定是try中的return語句呢?那么finally外的return b不是一點作用沒嗎?
public class FinallyTest1 { public static void main(String[] args) { System.out.println(test4()); } public static int test4() { int b = 20; try { System.out.println("try block"); b = b / 0; return b += 80; } catch (Exception e) { b += 15; System.out.println("catch block"); } finally { System.out.println("finally block"); if (b > 25) { System.out.println("b>25, b = " + b); } b += 50; } return b; } }
console:
try block catch block finally block b>25, b = 35 85
六:若發生異常,catch語句中的return語句和try中的return語句的情況一模一樣
public class FinallyTest1 { public static void main(String[] args) { System.out.println(test5()); } public static int test5() { int b = 20; try { System.out.println("try block"); b = b /0; return b += 80; } catch (Exception e) { System.out.println("catch block"); return b += 15; } finally { System.out.println("finally block"); if (b > 25) { System.out.println("b>25, b = " + b); } b += 50; } //return b; } }
console:
try block catch block finally block b>25, b = 35 35
總結:還是例1前面的一句話:
