java1.7 AutoCloseable接口和try-with-resources語法示例

2020-12-25 計算機java編程

AutoCloseable接口。

AutoCloseable接口非常簡單,只定義了一個close方法:

public interface AutoCloseable {

void close() Exception;

}

該接口是JDK 1.7 才新增的一個接口,方法文檔注釋該方法在try-with-resources語句中會被自動調用,用於自動釋放資源。

try-with-resources語句是JDK 1.7中一個新的異常處理機制,更方便簡潔的關閉在try-catch語句塊中使用的資源,這裡不得不提及傳統的資源釋放方式try-catch-finally:

byte[] b = new byte[1024];

FileInputStream fis = null;

try {

fis = new FileInputStream("my.txt");

int data = fis.read();

while(data != -1) {

data = fis.read(b);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

if (fis != null) {

try {

fis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

System.out.println(new String(b));

傳統的資源釋放方式是利用finally語句塊的特性,不管try語句塊裡是否拋出異常,finally語句塊均會被執行,該方式存在一個較隱蔽的問題,先看下面的改造示例:

byte[] b = new byte[1024];

FileInputStream fis = null;

try {

fis = new FileInputStream("my.txt");

int data = fis.read();

while (data != -1) {

data = fis.read(b);

}

throw new RuntimeException();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (Exception e) {

throw new RuntimeException();

} finally {

if (fis != null) {

try {

fis.close();

throw new IOException();

} catch (IOException e) {

throw new IOException();

}

}

}

System.out.println(new String(b));

本意是想捕獲RuntimeException的,但是因為finally語句塊的特性,拋出的IOException「抑制」了RuntimeException,外界捕獲到的是IOException,不便於準確的判斷問題所在。因為是根據調用棧向外拋出異常。

如果採用try-with-resources結構:

byte[] b = new byte[1024];

try(FileInputStream fis = new FileInputStream("my.txt")) {

int data = fis.read();

while (data != -1) {

data = fis.read(b);

}

}

System.out.println(new String(b));

代碼非常簡潔,而且FileInputStream資源會被自動關閉,且若拋出異常也是內部的確定異常。

byte[] b = new byte[1024];

try (FileInputStream fis = new FileInputStream("my.txt")) {

int data = fis.read();

while (data != -1) {

data = fis.read(b);

}

throw new RuntimeException();

}

當try-with-resources結構中拋出一個異常,同時fis被釋放時也拋出一個異常,最終向外拋出是try-with-resources內部的異常,反而FileInputStream資源釋放時的異常被抑制,剛好和try-catch-finally相反

若在try-with-resources結構中有多個資源需要被釋放,只要實現了AutoCloseable接口,均能被自動關閉:

byte[] b = new byte[1024];

try(

FileInputStream fis = new FileInputStream("my.txt");

BufferedInputStream bis = new BufferedInputStream(fis);

) {

int data = bis.read();

while (data != -1) {

data = fis.read(b);

}

}

System.out.println(new String(b));

關閉的順序是創建的順序的逆序。

Closeable接口繼承了AutoCloseable接口,故原有實現Closeable接口的類,均能在try-with-resources結構中使用。

也可以將自定義的類實現AutoCloseable接口,然後在try-with-resources結構中使用。

相關焦點

  • 為什麼推薦使用try-with-resources代替try-finally
    方法關閉,比如InputStream、OutputStream和java.sql.Connection。比如finalizer、try-catch-finally、try-with-resources等等。
  • 為什麼不推薦使用try-catch-finally處理Java異常?
    「    本文的所有例子均在本地代碼運行完畢       基於JDK版本1.8,運行環境eclipse       本文類名:TryWithResources,下文的堆棧信息也以此為基礎    」在java開發中,一些網絡連結或者是文件資源都需要程式設計師去手動調用close方法關閉,比如InputStream、OutputStream和java.sql.Connection
  • 每日一課 | 從Java中的文件讀取對象
    fin = new FileInputStream("c:\\temp\\address.ser");ObjectInputStream ois = new ObjectInputStream(fin);address = (Address) ois.readObject();1.
  • 跟我學java編程—使用try和catch捕獲異常
    前面了解了Java異常和異常處理類,本節講述如何使用try和catch語句捕獲異常。在java中添加捕獲異常代碼時,需要把認為可能會出現異常的代碼包括在try語句塊內,處理異常的代碼包括在catch語句內。在程序執行時,如果try語句內的代碼出現錯誤,try會創建異常對象並拋出,catch捕獲異常對象,則catch語句塊內的代碼將會執行,這樣就可以處理異常錯誤了。
  • Java 中的語法糖,真甜.
    我們在日常開發中經常會使用到諸如泛型、自動拆箱和裝箱、內部類、增強 for 循環、try-with-resources 語法、lambda 表達式等,我們只覺得用的很爽,因為這些特性能夠幫助我們減輕開發工作量;但我們未曾認真研究過這些特性的本質是什麼,那麼這篇文章,cxuan 就來為你揭開這些特性背後的真相。
  • Java經典面試題答案解析(1-80題)
    談談final在java中的作用?51. java中的Math.round(-1.5) 等於多少呢?Lambda 表達式:Lambda允許把函數作為一個方法的參數Stream API :新添加的Stream API(java.util.stream) 把真正的函數式編程風格引入到Java中方法引用:方法引用提供了非常有用的語法,可以直接引用已有Java類或對象(實例)的方法或構造器。默認方法:默認方法就是一個在接口裡面有了一個實現的方法。
  • Java中如何通過try優雅地釋放資源?
    時間緊迫,長話短說,今天,小明給大家同步一個知識點,使用try-with-resources來優雅地關閉資源。1.背景其實,在JDK 7就已經引入了對try-with-resources的支持,它的主要作用就是解放小明和小明小夥伴們的雙手,幫助我們自動釋放使用過的資源(比如輸入、輸出流)。2. 例子如何才能使用這個自動關閉資源的騷操作呢?
  • Java【IO系列】基礎篇—6. FileInputStream和FileOutputStream詳解
    本章介紹FileInputStream 和 FileOutputStream目錄1.
  • Java 基礎語法教程筆記
    源文件名:源文件名必須和類名相同。當保存文件的時候,你應該使用類名作為文件名保存(切記Java是大小寫敏感的),文件名的後綴為.java。(如果文件名和類名不相同則會導致編譯錯誤)。主方法入口:所有的Java 程序由public static void main(String []args)方法開始執行。Java所有的組成部分都需要名字。
  • 深入淺出Rhino:Java與JS互操作
    我們先來看看Java SE 8新增了哪些主要功能:  Java SE 8 新增主要功能  1、為提高開發人員工作效率,更好地利用多核處理器和增強對Java集合APIs的大容量數據處理功能,推出的Lambda表達式(「關閉」)。
  • 每日一課 | 如何將Java對象讀取和寫入文件
    如果Java對象的類或其任何超類實現java.io.Serializable接口或其子接口java.io.Externalizable ,則該對象是可序列化的。1.Java對象package com.mkyong; import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private
  • Spring Boot的JPA / Hibernate複合主鍵示例
    本文是JPA註解 @Embeddable和@EmbeddedId和複合主鍵的示例。假設我們有一個應用程式來管理各個公司的員工。每個員工在公司內都有一個獨特的員工。但同樣的員工也可以出現在其他公司中,所以我們不能僅僅通過他的員工身份來識別員工。要唯一地識別員工,我們需要知道他的employeeId和companyId兩者。
  • C++ auto和decltype的區別
    通過《C++ auto》和《C++ decltype》兩節的學習,相信大家已經掌握了 auto 和 decltype 的語法規則以及使用場景,這節我們將
  • JAVA8——JAVA成長之路
    第二種方法引用是靜態方法引用,它的語法是Class::static_method。請注意這個方法接受一個Car類型的參數。第三種方法引用是特定類的任意對象的方法引用,它的語法是Class::method。請注意,這個方法沒有參數。
  • Java 8 Map,Filter和Collect示例
    如何在Java 8中使用Map和Filter你需要一個很好的例子來理解這些概念。由於String和Integer是Java中最常見的數據類型,因此我選擇了一個既簡單又有趣的示例。我有一個String列表,例如{「1」,「2」,「3」,「4」,「5」,「6」}。我想處理這個列表,需要另一個只有偶數的整數列表。
  • Java筆試面試總結—try、catch、finally語句中有return 的各類情況
    前言之前在刷筆試題和面試的時候經常會遇到或者被問到 try-catch-finally  語法塊的執行順序等問題,今天就抽空整理了一下這個知識點,然後記錄下來。正文本篇文章主要是通過舉例的方式來闡述各種情況,我這裡根據 try-catch-finally 語法塊分為兩種大情況討論:try-catch 語法塊和 try-catch-finally 語句塊,然後再在每種情況裡再去具體討論。
  • 自從學會Java中的lambda表達式和函數式編程技巧,再也不用加班了!
    lambda表達式簡化了被註解的函數接口的使用,這些接口都聲明了一個抽象方法(當然它們也可以聲明默認,靜態和私有的方法)。比如,標準類庫提供了一java.lang.Runnable接口,其中包含一個抽象方法void run()。
  • Java程式設計師必備:異常的十個關鍵知識點
    = -1) {}}}Exceptionin thread "main" java.io.FileNotFoundException: jaywei.txt (系統找不到指定的文件。)即使try和catch中有return時,finally仍然會執行finally是在return後面的表達式運算完後再執行的。
  • java面試題總結:java的接口類和抽象類的特點
    java的接口類和抽象類的特點java中抽象類的特點:
  • 跟我學java編程—List接口實現類ArrayList
    前面三節介紹了Set接口的實現類HashSet、LinkedHashSet、TreeSet的基本用法,Set集合接口提供了存儲元素與Key的映射關係,可以通過Key去快速查找到對應的元素。從本節開始介紹List接口的實現類,List集合接口提供了元素的有序排列,List 接口的實現類在實現插入元素時,都會根據索引進行排列。