日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用try-with-resources替代try finally释放资源

發布時間:2023/12/19 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用try-with-resources替代try finally释放资源 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

1、舊社會

Java里,對于文件操作IO流、數據庫連接等開銷非常昂貴的資源,用完之后必須及時通過close方法將其關閉,否則資源會一直處于打開狀態,直至程序停止,增加系統負擔。

關閉資源的常用方式就是在finally塊里是釋放,即調用close方法。比如,我們經常會寫這樣的代碼:

public static void main(String[] args) {BufferedReader br = null;try {String line;br = new BufferedReader(new FileReader("d:\\testing.txt"));while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {// handle exception} finally {try {if (br != null) {br.close();}} catch (IOException ex) {// handle exception}} }

可以看出,為了關閉資源以及處理關閉資源時可能出現的異常,不得不寫一大推代碼。

2、新時代

2.1 使用新寫法

從Java 7開始,jdk提供了一種更好的方式關閉資源,使用try-with-resources語句,改寫一下上面的代碼,效果如下:

public static void main(String[] args) {try(BufferedReader br = new BufferedReader(new FileReader("d:\\testing.txt"))) {String line;while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {// handle exception} }

清爽了很多是不是? 但是,有沒有一點不安呢?

2.2 新問題

原來釋放資源的時候如果發生異常,我們可以在finally塊中catch新異常,然后繼續處理。但是新方式沒有了finally塊,異常是如何拋出的?如果關閉資源時發生異常怎么辦?我們怎么處理?

從文檔上可以找到這樣一段描述:

If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are suppressed. You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.

意思是:如果 try 塊拋出異常并且 try-with-resources 語句拋出一個或多個異常,那么從 try-with-resources 語句中拋出的異常將會被忽略。你可以通過調用由 try塊拋出的異常的Throwable.getSuppressed 方法檢索這些被忽略的異常信息。

在明確一點說就是:

  • 如果try塊異常,catch到的是try塊拋出的異常;
  • 如果try塊正常,close異常,catch到的是close拋出的異常;
  • 如果try塊異常,close也異常,catch到的是try塊拋出的異常,close異常被忽略。

基于這幾種情況,我們做幾個測試分別驗證一下:

2.2.1 try塊異常

大家都懂,略。

2.2.2 try塊正常,close異常

public class TestTryWithResources {public static void main(String[] args) {try (MyResource resource = new MyResource()) {} catch (Exception e) {System.out.println("捕獲異常: " + e.getMessage());}} }/*** 自定義一個資源類,close時拋出異常** ps:只有實現AutoCloseable或Closeable接口的對象才能用try-with-resources*/ class MyResource implements AutoCloseable {@Overridepublic void close() throws Exception {System.out.println("執行close方法,釋放資源");throw new Exception("釋放資源異常");} }

執行結果為: 執行close方法,釋放資源 捕獲異常: 釋放資源異常

即,catch到的是close方法拋出的異常

2.2.3 try塊異常,close也異常

public class TestTryWithResources {public static void main(String[] args) {try (MyResource resource = new MyResource()) {throw new Exception("try塊異常");} catch (Exception e) {System.out.println("捕獲異常: " + e.getMessage());// 找到被忽略的異常Throwable[] ts = e.getSuppressed();for(Throwable t : ts) {System.out.println("被忽略的異常"+ t.getMessage());}}} }/*** 自定義一個資源類,close時拋出異常*/ class MyResource implements AutoCloseable {@Overridepublic void close() throws Exception {System.out.println("執行close方法,釋放資源");throw new Exception("釋放資源異常");} }

執行結果: 執行close方法,釋放資源 捕獲異常: try塊異常 被忽略的異常: 釋放資源異常

即,catch到的是try塊中的異常,釋放資源時產生的異常被忽略了。

2.3 實踐中的問題

實際上,很多時候try塊中的異常和close方法拋出的異常是同一類型的。比如流、網絡等不論是try塊還是close方法都是拋出IOException,我們該怎么辦? 最佳實踐:按異常棧最底層的方法名判斷。如果是close方法拋出的異常,就是關閉資源時產生的。 注:我們的方法名不能叫close

public class TestTryWithResources {public static void main(String[] args) {try (MyResource resource = new MyResource()) {throw new Exception("try塊異常");} catch (Exception e) {if(!"close".equals(e.getStackTrace()[0].getMethodName())){System.out.println("處理業務異常");}}} }/*** 自定義一個資源類,close時拋出異常*/ class MyResource implements AutoCloseable {@Overridepublic void close() throws Exception {System.out.println("執行close方法,釋放資源");throw new Exception("釋放資源異常");} }

轉載于:https://my.oschina.net/u/145060/blog/701357

總結

以上是生活随笔為你收集整理的使用try-with-resources替代try finally释放资源的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。