• Java异常处理之try-with-resources


    Oracle官方文档: http://docs.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html

    概述

    Java SE 7以及后续版本中, 增加了 try-with-resources 语句,与传统 try 语句在结构上看在 try 后多了一个括号()

    1. try-with-resources语句是一个声明一个或多个资源的 try 语句。
    2. 任何实现了 Java.lang.AutoCloseable的对象, 包括所有实现了 java.io.Closeable 的对象, 都可以用作一个资源。
    3. 一个资源作为一个对象,必须在程序结束之后随之关闭。
    4. try-with-resources语句确保在语句的最后每个资源都被关闭 。
    5. 一个 try-with-resources 语句可以像普通的 try 语句那样有 catch 和 finally 块。在try-with-resources 语句中, 任意的 catch 或者 finally 块都是在声明的资源被关闭以后才运行。
    6. 形如
    try (
        try-with-resources 语句块
    ) 
    {
        try 语句块
    } catch() {
        statements
    } finally {
        statements
    }
    

    用例

    例1

    下面的例子读取文件的第一行。它使用了 BufferedReader 的一个实例来读取文件中的数据。这里BufferedReader 是一个资源,它必须在程序结束之后随之关闭:

    readFirstLineFromFile

        static String readFirstLineFromFile(String path) throws IOException {
          try (BufferedReader br = new BufferedReader(new FileReader(path))) {
            return br.readLine();
          }
        }
    
    1. 在这个例子中, try-with-resources 语句声明的资源是一个 BufferedReader。声明语句需要在紧跟在 try 关键字的括号里面。
    2. Java SE 7以及后续版本中,BufferedReader类实现了java.lang.AutoCloseable接口。
    3. 因为 BufferedReader 实例是在 try-with-resource 语句中声明的, 所以不管 try 语句正常地完成或是 发生意外 (结果就是 BufferedReader.readLine 方法抛出IOException),BufferedReader都将会关闭。

    例2

    readFirstLineFromFileWithFinallyBlock

    static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
          BufferedReader br = new BufferedReader(new FileReader(path));
          try {
            return br.readLine();
          } finally {
            if (br != null) br.close();
          }
        }
    
    1. 在 Java SE 7之前, 可以使用 finally 块来确保资源被关闭,不管 try 语句正常地完成或是发生意外。上面的例子使用 finally 块替换 try-with-resources 语句.
    2. 然而,在上面的例子中,如果 readLine 和 close 方法均抛出异常,那么readFirstLineFromFileWithFinallyBlock方法将抛出从 finally 块中抛出的异常,try 块中抛出的异常被挂起(Suppressed)。
    3. 与此相反, 在 readFirstLineFromFile 这个例子中, 如果 try 块和 try-with-resources 语句均抛出异常, 那么 readFirstLineFromFile 将抛出从 try 块中抛出的异常; try-with-resources 块抛出的异常被挂起。
    4. 在javaSE7以及后续的版本中,你可以检索挂起的异常(#1111);详情参见 Suppressed Exceptions
    5. 可以在一个 try-with-resources 语句中声明一个或多个资源。下面的例子检索zip文件 zipFileName 中所有文件的名称并创建一个包含那些文件名称的文本文件:

    例3

    import java.nio.charset.Charset;
    import java.nio.file.Path;
    import java.util.zip.ZipFile;
    import java.io.BufferedWriter;
    import java.nio.file.Files;
    import java.util.Enumeration;
    import java.util.zip;
    
    public static void writeToFileZipFileContents(String zipFileName, String outputFileName) 
                throws java.io.IOException {
    
            Charset charset = java.nio.charset.Charset.forName("US-ASCII");
            Path outputFilePath = java.nio.file.Paths.get(outputFileName);
            // 打开 zip 文件并使用 try-with-resources 语句创建输出文件
            try (
                    ZipFile zf = new java.util.zip.ZipFile(zipFileName);
                    BufferedWriter writer = Files.newBufferedWriter(outputFilePath, charset)
            ) {
                // 枚举每个表项
                for (Enumeration entries = zf.entries(); entries.hasMoreElements();) {
                    // 获取表项的名字并写入输出文件中
                    String newLine = System.getProperty("line.separator");
                    String zipEntryName = ((ZipEntry)entries.nextElement()).getName() + newLine;
                    writer.write(zipEntryName, 0, zipEntryName.length());
                }
            }
        }
    
    1. 在这个例子中, try-with-resources 语句包含两个由分号隔开的声明: ZipFile 和 BufferedWriter。
    2. 当代码块直接伴随着它正常地或由于一个异常终止时, BufferedWriter 和 ZipFile 对象的 close 方法以这种顺序自动地调用 。注意:资源的 close 方法调用顺序与它们的创建顺序相反。

    例4

    下面的例子使用一个 try-with-resources 语句来自动关闭一个 java.sql.Statement 对象:

    public static void viewTable(Connection con) throws SQLException {
          String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";
          try (Statement stmt = con.createStatement()) {
    ResultSet rs = stmt.executeQuery(query);
            while (rs.next()) {
              String coffeeName = rs.getString("COF_NAME");
              int supplierID = rs.getInt("SUP_ID");
              float price = rs.getFloat("PRICE");
              int sales = rs.getInt("SALES");
              int total = rs.getInt("TOTAL");
              System.out.println(coffeeName + ", " + supplierID + ", " + price +
                               ", " + sales + ", " + total);
            }
          } catch (SQLException e) {
            JDBCTutorialUtilities.printSQLException(e);
          }
        }
    

    挂起的异常(Suppressed Exceptions)

    1. 与 try-with-resources 语句关联的代码块可能会抛出异常。
    2. 在 writeToFileZipFileContents这个例子中, 当试图关闭 ZipFile 和 BufferedWriter 对象时,try 块可能会抛出一个异常,并且 try-with-resources 语句可能抛出多达两个异常 。
    3. 如果 try 块抛出异常并且 try-with-resources 语句抛出一个或多个异常,那么从 try-with-resources 语句中抛出的异常将会挂起, 并且块抛出的异常是由 writeToFileZipFileContents 方法抛出的那一个。
    4. 你可以通过调用由 try块抛出的异常的Throwable.getSuppressed 方法检索这些挂起的异常信息。

    实现了AutoCloseable 或 Closeable 接口的类

    1. Closeable 接口继承了 AutoCloseable 接口。
    2. Closeable接口的 close 方法抛出IOException 类型的异常而 AutoCloseable 接口的 close 方法抛出 Exception 类型的异常。因此, subclasses of the AutoCloseable 接口的子类可以重写 close 方法的这个行为来抛出指定的异常,例如 IOException, 或者没有异常。





  • 相关阅读:
    批处理
    命名规则
    注释
    HTML DOM属性
    OLTP
    修改HTML元素
    HTML
    工具资源系列之给虚拟机装个centos
    工具资源系列之给虚拟机装个windows
    工具资源系列之给mac装个虚拟机
  • 原文地址:https://www.cnblogs.com/nowgood/p/try-with-resources.html
Copyright © 2020-2023  润新知