使用try-with-resources替代try finally釋放資源

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

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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458321.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458321.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458321.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MFC模態對話框和非模態對話框

MFC中對話框有兩種形式,一個是模態對話框(model dialog box),一個是非模態對話框(modeless dialog box)。一、模態對話框(model dialog box)在程序運行的過程中,若出現了…

平板電腦離壽終正寢還有多遠?

近期有評論稱,因為大尺寸智能手機越來越普及,小尺寸平板正遭受著越來越嚴重的沖擊,在這樣的背景下,平板廠商也紛紛轉攻超大尺寸平板市場,以此避開大尺寸智能手機的競爭,只是。這樣的策略轉變是否能扭轉平板…

Swift 與 JSON 數據

轉載自: http://www.cnblogs.com/theswiftworld/p/4660177.html 我們大家平時在開發 App 的時候,相信接觸最多的就是 JSON 數據了。只要你的 App 有讀取網絡數據的功能,你就免不了要與 JSON 打交道。比如你做一個新聞 App,你要讀取…

TeamViewer - 最好用強大的免費跨平臺遠程桌面控制軟件 (支持電腦和手機)

from:很早以前 LYcHEE 就提到過,家中的潮人爺爺奶奶每天擺弄著電腦,看看新聞發發郵件,安享晚年生活。只是意料之中的,電腦上莫名出現各種問題?不翼而飛的圖標?照片又忘記怎么導出了?…

【設計模式】7、橋接模式

橋接模式就是對一個類的方法進行抽象化,吧不相關的因素提取出來,發展出第二個類 1 package com.shejimoshi.structural.Bridge;2 3 4 /**5 * 功能:橋接模式使用6 * 意圖:將抽象部分與它的實現部分分離,使他們都…

hadoop HA 之 QJM

前言 本文主要通過對hadoop2.2.0集群配置的過程加以梳理,所有的步驟都是通過自己實際測試。文檔的結構也是根據自己的實際情況而定,同時也會加入自己在實際過程遇到的問題。搭建環境過程不重要,重要點在于搭建過程中遇到的問題,解…

TeamViewer免費版和付費版有什么不同

提到遠程控制軟件 TeamViewer無疑是目前業內知名度比較高的一款,所以說到遠程控制軟件可能大部分人首先想到的就是TeamViewer。在使用功能上,它支持遠程桌面控制、文件傳輸、遠程計算機鎖定、視頻會話、主控方和被控方身份互換,遠程管理無人執…

iOS-關于cell的重疊問題

記得很早之前遇到過一個問題,關于cell的重疊問題,現在回顧總結一下。 iOS中tableview的cell顯示是會消耗內存的,如果要顯示無數個cell,不可能把每個cell都存儲下來,為了解決這個問題,cell就用了重用機制&am…

每天一個Linux命令-ls

ls 命令在linux系統中是使用頻率最頻繁的幾個命令之一,直接使用不帶目錄名,是默認顯示當前目錄的文件及子目錄名稱,ls加指定目錄名,則可以查看指定目錄下的文件及子目錄名稱,ls不僅可以查看目錄下有哪些文件和子目錄,還…

halcon資料鏈接

本文轉載自xiamentingtao,原文地址如下: http://blog.csdn.net/xiamentingtao/article/details/52583787 1目錄(?)[]論壇培訓博客文檔書籍視頻論壇、培訓halcon學習網:http://www.ihalcon.com/鳥叔機器視覺:http://bbs.szvbt.com…

【代碼筆記】iOS-翻書效果的實現

代碼: RootViewController.m #import "RootViewController.h"interface RootViewController ()endimplementation RootViewController- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {self [super initWithNibName:…

修改TFS與本地源代碼映射路徑

使用源代碼管理資源管理器修改工作區 在“文件”菜單上單擊“源代碼管理”,再單擊“工作區”。 在“管理工作區”對話框的“名稱”列下,突出顯示要修改的工作區,然后單擊“編輯”。 在“編輯工作區”對話框中: 修改“名稱”框中…

halcon基礎知識

一、程序中的顏色: 綠色:注釋 褐色:控制開發 淺藍色:外部函數——HDevelop函數文件,可在所有Halcon程序中使用 深藍色:圖像獲取和處理 紫色:內部函數——本地程序函數,只在當前程序使…

停止過度設計,開發客戶需要的軟件

在與許多不同的團隊合作過之后,Greg Young發現大家做項目時經常會大幅度的過度設計。比如一個預計要開發9個月的項目,換個角度思考一下,卻可能只需要幾個星期就可以提交95%的功能。Young在最近倫敦舉行的DDD eXchange大會上著重闡述了這一點。…

Halcon—Tuple中符號的含義

2014年08月08日 21:20:30閱讀數:5429實例一(3d_coordinates.hdev):for I : 1 to NumImages by 1read_image (Image, calib/calib-3d-coord-I$02d)——C:\Program Files\MVTec\HALCON-10.0\images\的calib文件夾中開頭是calib-3d-c…

如果我是博客園的產品經理【上】

題記 這是一個系列文章的第一篇 我打算寫一個《如果我是XXX的產品經理》系列, 因為我是博客園的老用戶了,這個系列又是寫在博客園上的 所以先拿博客園開刀, 后面估計還會寫QQ音樂,有道云筆記,github,foxmai…

Halcon學習筆記(三)---數據類型

Halcon學習筆記(三)---數據類型halcon只能在單獨行進行注釋,不能在語句后面進行注釋。1、tuple(元組,重數)賦值符號“:”tuple算子:(1)變量定義與加減乘除運算代碼如下:*…

論文筆記之:RATM: RECURRENT ATTENTIVE TRACKING MODEL

RATM: RECURRENT ATTENTIVE TRACKING MODEL ICLR 2016 本文主要內容是 結合 RNN 和 attention model 用來做目標跟蹤。 其中模型的組成主要是: 1. an attention model 主要用來從輸入圖像中提取 patch; 2. RNN 用來預測 attention 參數,即&am…

【分享】WeX5的正確打開方式(5)——綁定機制

今天繼續WeX5的綁定機制。 需求分析 記賬本要實現的效果就是可以展示所有賬單,還能實時動態編輯每一筆賬單,官方案例的效果圖如下: 展示頁: 編輯頁 個人覺得官方案例加入了許多元素,不熟悉的同學每一個點都很難理解&am…

HALCON常用算子(HALCON13.0)

HALCON常用算子(HALCON13.0)Chapter 9--Developdev_clear_window ( : : : )功能:清除活動圖形窗口的內容dev_close_window ( : : : )功能:關閉活動圖形窗口。dev_display ( Object : : : )功能:在現有圖形窗口中顯示圖…