欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java如何優(yōu)雅地關(guān)閉資源try-with-resource及其異常抑制

 更新時(shí)間:2019年02月13日 11:16:44   作者:敲代碼的小阿貍  
這篇文章主要介紹了Java如何優(yōu)雅地關(guān)閉資源try-with-resource及其異常抑制,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

一、背景

我們知道,在Java編程過程中,如果打開了外部資源(文件、數(shù)據(jù)庫連接、網(wǎng)絡(luò)連接等),我們必須在這些外部資源使用完畢后,手動(dòng)關(guān)閉它們。因?yàn)橥獠抠Y源不由JVM管理,無法享用JVM的垃圾回收機(jī)制,如果我們不在編程時(shí)確保在正確的時(shí)機(jī)關(guān)閉外部資源,就會(huì)導(dǎo)致外部資源泄露,緊接著就會(huì)出現(xiàn)文件被異常占用,數(shù)據(jù)庫連接過多導(dǎo)致連接池溢出等諸多很嚴(yán)重的問題。

 二、傳統(tǒng)的資源關(guān)閉方式

為了確保外部資源一定要被關(guān)閉,通常關(guān)閉代碼被寫入finally代碼塊中,當(dāng)然我們還必須注意到關(guān)閉資源時(shí)可能拋出的異常,于是變有了下面的經(jīng)典代碼:

public static void main(String[] args) {
  FileInputStream inputStream = null;
  try {
    inputStream = new FileInputStream(new File("test"));
    System.out.println(inputStream.read());
  } catch (IOException e) {
    throw new RuntimeException(e.getMessage(), e);
  } finally {
    if (inputStream != null) {
      try {
        inputStream.close();
      } catch (IOException e) {
        throw new RuntimeException(e.getMessage(), e);
      }
    }
  }
}

熟悉其他語言的朋友可能會(huì)開始吐槽了,在C++中,我們可以把關(guān)閉資源的代碼放在析構(gòu)函數(shù)中,在C#中,我們有using代碼塊。這些語法都有一個(gè)共同的特性,讓外部資源的關(guān)閉行為與外部資源的句柄對(duì)象的生命周期關(guān)聯(lián),當(dāng)外部資源的句柄對(duì)象生命周期終結(jié)時(shí)(例如句柄對(duì)象已出作用域),外部資源的關(guān)閉行為將被自動(dòng)調(diào)用。這樣不僅更加符合面向?qū)ο蟮木幊汤砟睿▽㈥P(guān)閉外部資源的行為內(nèi)聚在外部資源的句柄對(duì)象中),也讓代碼更加簡(jiǎn)潔易懂。怎么到了Java這里,就找不到自動(dòng)關(guān)閉外部資源的語法特性了呢。

三、JDK7及其之后的資源關(guān)閉方式

3.1 try-with-resource語法

確實(shí),在JDK7以前,Java沒有自動(dòng)關(guān)閉外部資源的語法特性,直到JDK7中新增了try-with-resource語法,才實(shí)現(xiàn)了這一功能。

那什么是try-with-resource呢?簡(jiǎn)而言之,當(dāng)一個(gè)外部資源的句柄對(duì)象(比如FileInputStream對(duì)象)實(shí)現(xiàn)了AutoCloseable接口,那么就可以將上面的板式代碼簡(jiǎn)化為如下形式:

public static void main(String[] args) {
  try (FileInputStream inputStream = new FileInputStream(new File("test"))) {
    System.out.println(inputStream.read());
  } catch (IOException e) {
    throw new RuntimeException(e.getMessage(), e);
  }
}

將外部資源的句柄對(duì)象的創(chuàng)建放在try關(guān)鍵字后面的括號(hào)中,當(dāng)這個(gè)try-catch代碼塊執(zhí)行完畢后,Java會(huì)確保外部資源的close方法被調(diào)用。代碼是不是瞬間簡(jiǎn)潔許多!

3.2 實(shí)現(xiàn)原理

try-with-resource并不是JVM虛擬機(jī)的新增功能,只是JDK實(shí)現(xiàn)了一個(gè)語法糖,當(dāng)你將上面代碼反編譯后會(huì)發(fā)現(xiàn),其實(shí)對(duì)JVM虛擬機(jī)而言,它看到的依然是之前的寫法:

public static void main(String[] args) {
  try {
    FileInputStream inputStream = new FileInputStream(new File("test"));
    Throwable var2 = null;

    try {
      System.out.println(inputStream.read());
    } catch (Throwable var12) {
      var2 = var12;
      throw var12;
    } finally {
      if (inputStream != null) {
        if (var2 != null) {
          try {
            inputStream.close();
          } catch (Throwable var11) {
            var2.addSuppressed(var11);
          }
        } else {
          inputStream.close();
        }
      }

    }

  } catch (IOException var14) {
    throw new RuntimeException(var14.getMessage(), var14);
  }
}

3.3 異常抑制

通過反編譯的代碼,大家可能注意到代碼中有一處對(duì)異常的特殊處理:

var2.addSuppressed(var11);

這是try-with-resource語法涉及的另外一個(gè)知識(shí)點(diǎn),叫做異常抑制。當(dāng)對(duì)外部資源進(jìn)行處理(例如讀或?qū)懀r(shí),如果遭遇了異常,且在隨后的關(guān)閉外部資源過程中,又遭遇了異常,那么你catch到的將會(huì)是對(duì)外部資源進(jìn)行處理時(shí)遭遇的異常,關(guān)閉資源時(shí)遭遇的異常將被“抑制”但不是丟棄,通過異常的getSuppressed方法,可以提取出被抑制的異常。

四、總結(jié)

1、當(dāng)一個(gè)外部資源的句柄對(duì)象實(shí)現(xiàn)了AutoCloseable接口,JDK7中便可以利用try-with-resource語法更優(yōu)雅的關(guān)閉資源,消除板式代碼。

2、try-with-resource時(shí),如果對(duì)外部資源的處理和對(duì)外部資源的關(guān)閉均遭遇了異常,“關(guān)閉異常”將被抑制,“處理異?!睂⒈粧伋?,但“關(guān)閉異?!辈]有丟失,而是存放在“處理異?!钡谋灰种频漠惓A斜碇?。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java編程實(shí)現(xiàn)根據(jù)EXCEL列名求其索引的方法

    java編程實(shí)現(xiàn)根據(jù)EXCEL列名求其索引的方法

    這篇文章主要介紹了java編程實(shí)現(xiàn)根據(jù)EXCEL列名求其索引的方法,涉及Java元素遍歷與數(shù)學(xué)運(yùn)算的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • 從零開始學(xué)SpringBoot如何開始使用圖文詳解

    從零開始學(xué)SpringBoot如何開始使用圖文詳解

    這篇文章主要介紹了從零開始學(xué)SpringBoot如何開始使用,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java 程序初始化順序

    Java 程序初始化順序

    這篇文章主要介紹了Java 程序初始化順序,在Java語言中,當(dāng)實(shí)例化對(duì)象時(shí),對(duì)象所在類的所有成員變量首先要進(jìn)行初始化,只有當(dāng)所有的類成員完成了初始化之后,才會(huì)調(diào)用對(duì)象所在類的構(gòu)造函數(shù)創(chuàng)建對(duì)象,需要的朋友可以參考一下
    2022-01-01
  • Maven?項(xiàng)目用Assembly打包可執(zhí)行jar包的方法

    Maven?項(xiàng)目用Assembly打包可執(zhí)行jar包的方法

    這篇文章主要介紹了Maven?項(xiàng)目用Assembly打包可執(zhí)行jar包的方法,該方法只可打包非spring項(xiàng)目的可執(zhí)行jar包,需要的朋友可以參考下
    2023-03-03
  • SpringBoot 如何實(shí)時(shí)刷新靜態(tài)文件

    SpringBoot 如何實(shí)時(shí)刷新靜態(tài)文件

    這篇文章主要介紹了SpringBoot如何實(shí)時(shí)刷新靜態(tài)文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • idea切換git地址并刷新右下角git分支

    idea切換git地址并刷新右下角git分支

    這篇文章主要介紹了idea切換git地址并刷新右下角git分支,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java 在PDF中添加騎縫章示例解析

    Java 在PDF中添加騎縫章示例解析

    這篇文章主要介紹了Java 在PDF中添加騎縫章示例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • SpringBoot?自定義注解實(shí)現(xiàn)涉密字段脫敏

    SpringBoot?自定義注解實(shí)現(xiàn)涉密字段脫敏

    關(guān)于數(shù)據(jù)脫敏,網(wǎng)上的文章都是硬編碼規(guī)則,比如對(duì)身份證,手機(jī)號(hào),郵件地址等固定寫法脫敏。本文在此基礎(chǔ)上,拓展動(dòng)態(tài)從數(shù)據(jù)庫查出涉密關(guān)鍵字執(zhí)行脫敏操作。感興趣的同學(xué)可以參考閱讀
    2023-03-03
  • Java集合Map的clear與new Map區(qū)別詳解

    Java集合Map的clear與new Map區(qū)別詳解

    這篇文章主要介紹了Java集合Map的clear與new Map區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • springboot 整合 OpenTelemetry的解決方案

    springboot 整合 OpenTelemetry的解決方案

    這篇文章主要介紹了springboot 整合 OpenTelemetry的解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-01-01

最新評(píng)論