📜  Java9 try-with-resource功能(1)

📅  最后修改于: 2023-12-03 15:16:03.120000             🧑  作者: Mango

Java9 try-with-resource功能

在Java9中,try-with-resource增强了它的功能。try-with-resource语句是一种方便的确保资源在使用后被关闭的方法,这些资源必须在try子句中声明。在Java9之前,只能将单个资源声明为try-with-resource语句中的资源。而在Java9中,允许在try子句中声明多个资源。

为什么需要try-with-resource

在Java中,访问文件,数据库连接,网络连接等资源时,需要打开这些资源并提供访问这些资源的访问权限。这些资源不是无限制的,可能会达到存储器限制以及其他限制。因此,资源使用必须经过正确的管理。为了自动管理这些资源,try-with-resources出现了。使用try-with-resources可以保证在执行完try语句块后自动关闭资源,并且资源的顺序是反向的(即最后声明的资源最先关闭)。

使用try-with-resource

在Java 7中,基本的try-with-resource代码如下:

public static void copy(String file1, String file2) throws IOException {
    try (InputStream in = new FileInputStream(file1);
         OutputStream out = new FileOutputStream(file2)) {
        byte[] buf = new byte[8192];
        int n;
        while ((n = in.read(buf)) >= 0)
            out.write(buf, 0, n);
    }
}

在Java 9中,多个资源的try-with-resource语句仅需要在一个括号中声明即可:

public static void copy(String file1, String file2) throws IOException {
    try (InputStream in = new FileInputStream(file1);
         OutputStream out = new FileOutputStream(file2)) {
        byte[] buf = new byte[8192];
        int n;
        while ((n = in.read(buf)) >= 0)
            out.write(buf, 0, n);
    }
}
try-with-resource中新特性

在Java 9中,try-with-resource功能还添加了以下新特性:

1. 对try-with-resource资源的完全控制

在Java9以前,try-with-resource块中声明的变量不可重新分配,但现在Java9允许修改和重新初始化try-with-resource块中的资源变量。这允许开发人员更细致地控制资源(甚至是修改或重新初始化资源)。

InputStream in = new FileInputStream(file);
try (in) {
    in.read();
} finally {
    in = null; // 修改变量
}
2. 强制在所有处理异常之后关闭资源

在Java9之前,在处理异常时,可能会忘记调用close()方法以关闭资源。为了解决这个问题,Java9增加了一种新的机制,以确保实现在所有处理异常之后关闭资源,即通过Throwable.addSuppressed()方法抛出异常。

OutputStream out1 = new FileOutputStream(file1);
OutputStream out2 = new FileOutputStream(file2);
try (out1; out2) {
    out1.write(data);
    throw new IOException("Test");
} catch (IOException e) {
    out2.write(data); // 如果是异常,资源将处理并关闭
    e.addSuppressed(new IOException("Test2"));
    throw e;
}
3. 多个异常情况的精细处理

Java 7之前,try-with-resource只支持一种资源和一个异常类型。例如,ConnectionStatement。在Java 7中,可以有多种资源和一种异常类型。例如,ConnectionStatementResultSet。在Java 9中,我们可以有多个资源和多个异常类型。例如,ConnectionSessionStatementResultSetSQLException

try (Connection conn = DriverManager.getConnection(url);
     Statement stmt = conn.createStatement();
     ResultSet rs = stmt.executeQuery(query)) {
  // 执行事务
} catch (SQLException | IOException e) { // 引入多个异常
  throw new RuntimeException(e);
}
总结

try-with-resource是Java 7中引入的功能,可以在资源使用后自动关闭它们。在Java 9中,try-with-resource功能进一步增强,允许声明多个资源,并允许精细地控制资源的关闭。通过使用try-with-resource,可以编写更简单,更有效的代码,同时避免资源泄漏和错误处理。