【Java】finally用法

一.概述

  1. 本文說明Java中finally的用法和可能遇到的坑
  2. finally的目的是保證代碼被執行,但也會存在不執行的情況
  3. finally 代碼塊的原理是複製 finally 代碼塊的內容,分別放在 try-catch 代碼塊所有正常執行路徑以及異常執行路徑的出口中。
    所以不管是是正常還是異常執行,finally都是最後執行的。

二. finally會執行的情況

1.有catch(無異常)

try {
    System.out.println("try execute");
    
} catch (RuntimeException e) {
    System.out.println("catch execute");
    
} finally {
    System.out.println("finally execute");
}
輸出
try execute
finally execute

3.有catch(try異常)

try {
    System.out.println("try execute");
    throw new RuntimeException("try Exception");

} catch (Exception e) {
    System.out.println("catch execute");

} finally {
    System.out.println("finally execute");
}
輸出
try execute
catch execute
finally execute

4.有catch(catch異常)

try {
    System.out.println("try execute");

} catch (Exception e) {
    System.out.println("catch execute");
    throw new RuntimeException("catch Exception");

} finally {
    System.out.println("finally execute");
}
輸出
try execute
finally execute

5.有catch(try/catch都異常)(會拋出異常)

 try {
    System.out.println("try execute");
    throw new RuntimeException("try Exception");

} catch (Exception e) {
    System.out.println("catch execute");
    throw new RuntimeException("catch Exception");

} finally {
    System.out.println("finally execute");
}
輸出
try execute
catch execute
finally execute
Exception in thread "main" RuntimeException: catch Exception

6. 沒有catch(無異常)

try {
    System.out.println("try execute");
} finally {
    System.out.println("finally execute");
}
輸出
try execute
finally execute

7. 沒有catch(try異常)(會拋出異常)

try {
    System.out.println("try execute");
    throw new RuntimeException("try Exception");

} finally {
    System.out.println("finally execute");
}
輸出
try execute
finally execute
Exception in thread "main" ServiceException: try Exception

8. 有返回值(try)(程序返回"try return")

try {
    System.out.println("try execute");
    return "try return";

} finally {
    System.out.println("finally execute");
}
輸出
try execute
finally execute

9. 有返回值(catch)(程序返回"catch return")

try {
    System.out.println("try execute");
    throw new RuntimeException("try exception");

} catch (Exception ex) {
    return "catch return";
} finally {
    System.out.println("finally execute");
}
輸出
try execute
finally execute

三. finally不會執行的情況

1. 調用 System.exit 函數

try {
    System.out.println("try execute");
    System.exit(1);

} catch (Exception ex) {

    System.out.println("catch execute");

} finally {

    System.out.println("finally execute");
}
輸出
try execute

2. 調用 halt 函數

try {
    System.out.println("try execute");
    Runtime.getRuntime().halt(1);

} catch (Exception ex) {

    System.out.println("catch execute");

} finally {

    System.out.println("finally execute");
}
輸出
try execute

四. 常見問題

1. 忽略異常(程序返回"finally return")

try {
    System.out.println("try execute");
    throw new RuntimeException("try exception");

} finally {

    System.out.println("finally execute");
    return "finally return";
}
輸出
try execute
finally execute

2. finally存在return語句,則 try 和 catch 存在的返回語句就會被忽略(程序返回"finally return")

try {
    System.out.println("try execute");
    return "try return";

} finally {
    System.out.println("finally execute");
    return "finally return";
}
輸出
try execute
finally execute

3. finally拋異常(不會有返回值,一直拋出異常 RuntimeException)

try {
    System.out.println("try execute");
    return "try return";

} finally {

    System.out.println("finally execute");
    throw new RuntimeException("finally exception");
}
輸出
try execute
finally execute
Exception in thread "main" java.lang.RuntimeException: finally exception

4. finally異常覆蓋try異常

try {
    System.out.println("try execute");
    throw new RuntimeException("try exception");

} finally {

    System.out.println("finally execute");
    throw new RuntimeException("finally exception");
}
輸出
try execute
finally execute
Exception in thread "main" java.lang.RuntimeException: finally exception

5. finally異常覆蓋catch異常

try {
    System.out.println("try execute");
    throw new RuntimeException("try exception");

} catch (Exception ex) {

    System.out.println("catch execute");
    throw new RuntimeException("catch exception");

} finally {

    System.out.println("finally execute");
    throw new RuntimeException("finally exception");
}
輸出
Exception in thread "main" java.lang.RuntimeException: finally exception
try execute
catch execute
finally execute

6. finally異常覆蓋其它異常原因及解決

原因:一個方法只能拋出一種異常,無法出現兩種

解決1:finally代碼塊自行捕獲和處理異常

try {
    System.out.println("try execute");

} finally {

    System.out.println("finally execute");

    try {

        throw new RuntimeException("finally exception");

    } catch (Exception ex) {

        log.error(ex.getMessage());
    }
}
輸出
try execute
finally execute
錯誤日誌:finally exception

解決2:異常追加

Exception e = null;

try {
    System.out.println("try execute");
    throw new RuntimeException("try exception");

} catch (Exception ex) {
    System.out.println("catch execute");
    e = ex;

} finally {
    System.out.println("finally execute");
    try {

        throw new RuntimeException("finally exception");

    } catch (Exception ex) {

        if (e != null) {
            e.addSuppressed(ex);
        } else {
            e = ex;
        }
    }
}

throw e;
輸出
try execute
catch execute
finally execute
Exception in thread "main" java.lang.RuntimeException: try exception
    Suppressed: java.lang.RuntimeException: finally exception
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章