【Java】finally用法
阿新 • • 發佈:2021-11-05
目錄
一.概述
- 本文說明Java中finally的用法和可能遇到的坑
- finally的目的是保證程式碼被執行,但也會存在不執行的情況
- 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