[Java開發之路](20)try-with-resource 異常聲明


Try-with-resources是java7中一個新的異常處理機制,它能夠很容易地關閉在try-catch語句塊中使用的資源。

在java7以前,程序中使用的資源需要被明確地關閉,過程有點繁瑣,如下所示:

 
 
  1. package com.qunar.lectures.tryResource;
  2. import java.io.*;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. /**
  6. * Created by xiaosi on 16-3-4.
  7. */
  8. public class TryResourceDemo {
  9.    // 獲取資源數據
  10.    public static List<String> readLines(String resourcePath) {
  11.        String path = TryResourceDemo.class.getResource(resourcePath).getPath();
  12.        File file = new File(path);
  13.        if (!file.exists()) {
  14.            throw new RuntimeException("Can not find file + " + resourcePath);
  15.        }//if
  16.        if (!file.isFile()) {
  17.            throw new RuntimeException(resourcePath + " is not a regular file");
  18.        }//if
  19.        FileInputStream fis;
  20.        InputStreamReader isr;
  21.        BufferedReader br = null;
  22.        try {
  23.            fis = new FileInputStream(file);
  24.            isr = new InputStreamReader(fis, "UTF-8");
  25.            br = new BufferedReader(isr);
  26.            List<String> lines = new ArrayList<String>();
  27.            String line;
  28.            while ((line = br.readLine()) != null) {
  29.                lines.add(line);
  30.            }//while
  31.            return lines;
  32.        }
  33.        catch (IOException e) {
  34.            throw new RuntimeException("Read file failed , file=" + resourcePath, e);
  35.        }
  36.        finally {
  37.            if(br != null){
  38.                try {
  39.                    br.close();
  40.                } catch (IOException e) {
  41.                    e.printStackTrace();
  42.                }
  43.            }//if
  44.        }//finally
  45.    }
  46.    public static void main(String[] args) {
  47.        List<String> lines = readLines("/a.txt");
  48.        for(String line : lines){
  49.            System.out.println("line:" + line);
  50.        }//for
  51.    }
  52. }


假設try語句塊拋出一個異常,然后finally語句塊被執行。同樣假設finally語句塊也拋出了一個異常。那么哪個異常會根據調用棧往外傳播?即使try語句塊中拋出的異常與異常傳播更相關,最終還是finally語句塊中拋出的異常會根據調用棧向外傳播。

 
 
  1. private static void printFileJava7() throws IOException {
  2.    try(FileInputStream input = new FileInputStream("file.txt")) {
  3.        int data = input.read();
  4.        while(data != -1){
  5.            System.out.print((char) data);
  6.            data = input.read();
  7.        }
  8.    }
  9. }

我們看到第一行:

 
 
  1. try(FileInputStream input = new FileInputStream("file.txt")) {

這就是try-with-resource 結構的用法。FileInputStream 類型變量就在try關鍵字后面的括號中聲明並賦值。在這聲明的變量我們可以在下面的代碼中直接使用,即同一個作用域中。當try語句塊運行結束時,FileInputStream會被自動關閉。這是因為FileInputStream 實現了java中的java.lang.AutoCloseable接口。所有實現了這個接口的類都可以在try-with-resources結構中使用。

當try-with-resources結構中拋出一個異常,同時FileInputStreami被關閉時(調用了其close方法)也拋出一個異常,try-with-resources結構中拋出的異常會向外傳播,而FileInputStreami被關閉時拋出的異常被抑制了。這與文章開始處利用舊風格代碼的例子(在finally語句塊中關閉資源)相反。

在JDK7中只要實現了AutoCloseable或Closeable接口的類或接口,都可以使用try-with-resource來實現異常處理和資源關閉。

你可以在塊中使用多個資源而且這些資源都能被自動地關閉:

 
 
  1. package com.qunar.lectures.tryResource;
  2. import java.io.*;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. /**
  6. * Created by xiaosi on 16-3-4.
  7. */
  8. public class TryResourceDemo {
  9.    // 獲取資源數據
  10.    public static List<String> readLines(String resourcePath) {
  11.        String path = TryResourceDemo.class.getResource(resourcePath).getPath();
  12.        File file = new File(path);
  13.        if (!file.exists()) {
  14.            throw new RuntimeException("Can not find file + " + resourcePath);
  15.        }//if
  16.        if (!file.isFile()) {
  17.            throw new RuntimeException(resourcePath + " is not a regular file");
  18.        }//if
  19.        // try-with-resource方式 自動釋放資源
  20.        try (FileInputStream fis = new FileInputStream(file);
  21.             InputStreamReader isr = new InputStreamReader(fis);
  22.                BufferedReader br = new BufferedReader(isr)){
  23.            List<String> lines = new ArrayList<String>();
  24.            String line;
  25.            while ((line = br.readLine()) != null) {
  26.                lines.add(line);
  27.            }//while
  28.            return lines;
  29.        }
  30.        catch (IOException e) {
  31.            throw new RuntimeException("Read file failed , file=" + resourcePath, e);
  32.        }
  33.    }
  34.    public static void main(String[] args) {
  35.        List<String> lines = readLines("/a.txt");
  36.        for(String line : lines){
  37.            System.out.println("line:" + line);
  38.        }//for
  39.    }
  40. }






注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com