溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java try()語句實現(xiàn)try-with-resources異常管理機(jī)制的操作方法

發(fā)布時間:2021-09-24 15:24:22 來源:億速云 閱讀:134 作者:柒染 欄目:開發(fā)技術(shù)

Java try()語句實現(xiàn)try-with-resources異常管理機(jī)制的操作方法,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

Java try()語句實現(xiàn)try-with-resources異常管理機(jī)制

java7 新增特性,對于try語句塊中使用到的資源,不再需要手動關(guān)閉,在語句塊結(jié)束后,會自動關(guān)閉,類似于python的with..as的用法。

利用這個特性,需要實現(xiàn)AutoCloseable接口,只有一個close方法,實現(xiàn)關(guān)閉資源的操作。

public interface AutoCloseable{
    public void close() throws Exception;
}

所有的流,都實現(xiàn)了這個接口,可以在try()中進(jìn)行實例化。自定義的類只要實現(xiàn)了這個接口,也可以使用這個特性。

不使用try-with-resources時,使用的資源要在finally中進(jìn)行釋放

package stream; 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; 
public class TestStream { 
    public static void main(String[] args) {
        File f = new File("d:/test.txt");
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(f); 
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 在finally 里關(guān)閉流
            if (null != fis)
                try { 
                    fis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        } 
    }
}

使用try-with-resources時

形式為try(),括號內(nèi)可以包含多個語句。

package stream;  
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;  
public class TestStream {  
    public static void main(String[] args) {
        File f = new File("d:/lol.txt");
  
        //把流定義在try()里,try,catch或者finally結(jié)束的時候,會自動關(guān)閉
        try (FileInputStream fis = new FileInputStream(f)) {
            byte[] all = new byte[(int) f.length()];
            fis.read(all);
            for (byte b : all) {
                System.out.println(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }  
    }
}

自定義AutoCloseable實現(xiàn)

在TestAutoCloseable的close方法中打印信息

package test; 
public class TestAutoCloseable implements AutoCloseable{
 public TestAutoCloseable() {
  System.out.println("class TestAutoCloceable");
 }
 public void close() {
  System.out.println("function close() executed");
 }
}

測試代碼

package test; 
public class TestFeature { 
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  try(TestAutoCloseable testAutoCloseable = new TestAutoCloseable()){   
  }
 } 
}

結(jié)果close方法被調(diào)用

Java try()語句實現(xiàn)try-with-resources異常管理機(jī)制的操作方法

try-with-resources語句優(yōu)雅的關(guān)閉資源

在Java編程過程中,如果打開了外部資源(文件、數(shù)據(jù)庫連接、網(wǎng)絡(luò)連接等),我們必須在這些外部資源使用完畢后,手動關(guān)閉它們。

因為外部資源不由JVM管理,無法享用JVM的垃圾回收機(jī)制,如果我們不在編程時確保在正確的時機(jī)關(guān)閉外部資源,就會導(dǎo)致外部資源泄露,緊接著就會出現(xiàn)文件被異常占用,數(shù)據(jù)庫連接過多導(dǎo)致連接池溢出等諸多很嚴(yán)重的問題。

在java1.7以前,我們關(guān)閉資源的方式如下

public class CloseTest {
    public static void main(String[] args){ 
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream("file.txt");
            fileInputStream.read();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fileInputStream != null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

為了確保外部資源一定要被關(guān)閉,通常關(guān)閉代碼被寫入finally代碼塊中,關(guān)閉資源時可能拋出的異常,于是經(jīng)典代碼就誕生了。

但是,在java1.7版本之后,新增加了一個語法糖,就是try-with-resources語句,

我們先直接上一個demo,方便理解

public class CloseTest {
    public static void main(String[] args) {
        try (FileInputStream fileInputStream1 = new FileInputStream("file1.txt");
             FileInputStream fileInputStream2 = new FileInputStream("file2.txt")) {
            fileInputStream1.read();
            fileInputStream2.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

將外部資源的句柄對象的創(chuàng)建放在try關(guān)鍵字后面的括號中,當(dāng)這個try-catch代碼塊執(zhí)行完畢后,Java會確保外部資源的close方法被調(diào)用。多個語句使用分號斷開。

反編譯之后我們可以看見

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);
  }
}

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

var2.addSuppressed(var11);

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

源碼里面有解釋

 /**
     * Returns an array containing all of the exceptions that were
     * suppressed, typically by the {@code try}-with-resources
     * statement, in order to deliver this exception.
     *
     * If no exceptions were suppressed or {@linkplain
     * #Throwable(String, Throwable, boolean, boolean) suppression is
     * disabled}, an empty array is returned.  This method is
     * thread-safe.  Writes to the returned array do not affect future
     * calls to this method.
     *
     * @return an array containing all of the exceptions that were
     *         suppressed to deliver this exception.
     * @since 1.7
     */
    public final synchronized Throwable[] getSuppressed() {
        if (suppressedExceptions == SUPPRESSED_SENTINEL ||
            suppressedExceptions == null)
            return EMPTY_THROWABLE_ARRAY;
        else
            return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
    }

因為不管什么情況下(異?;蛘叻钱惓?資源都必須關(guān)閉,在jdk1.6之前,應(yīng)該把close()放在finally塊中,以確保資源的正確釋放。如果使用jdk1.7以上的版本,推薦使用try-with-resources語句。

關(guān)于Java try()語句實現(xiàn)try-with-resources異常管理機(jī)制的操作方法問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI