JavaSE7 特性 try-with-resources语句,你用过吗?


前言

Java SE 7 的特性 try-with-resources 语句,你用过吗?为什么会有这篇文章呢?主要是在写 Java EE 小白入门专栏时,在 JDBC 章节中有提到过:JDBC 编程基本步骤中一般最后一步是关闭相关资源,可能涉及到 ConnectionPreparedStatementResultSet 资源关闭。在 Java SE 7 及更高版本中我们可以使用 try-with-resources 语句进行优化,但是由于看到示例代码,觉得使用后会有点乱,自己不适应,就没有去尝试。现在想想既然官方有这个特性,明确说明可以简化代码,那说明并不是我想的那样,所以就有了这篇文章。


一、try-with-resources语句

1.try-with-resources语句介绍

首先我们来看官方的说明:

try-with-resources 语句是声明一个或多个资源的 try 语句。资源是一个对象,在程序使用完它之后必须关闭它。try-with-resources 语句确保在语句结束时关闭每个资源。任何实现 java.lang.AutoCloseable,它包括所有实现java.io.AutoCloseable 的对象,都可作为资源使用。

个人觉得官方说得比较清楚,凡是实现了 java.lang.AutoCloseablejava.io.AutoCloseable 的资源对象,都可以使用 try-with-resources 语句,在 try 块中语句执行结束后,资源自动关闭。就是这个意思。

那么 try-with-resources 是 Java 7 及更高版本中引入的一个特性,用于更好地管理资源,如文件、网络连接、数据库连接等。这个特性的主要目标是自动关闭在 try 块中打开的资源,无论 try 块是否正常结束或抛出异常。这有助于防止资源泄漏,并使代码更易于理解和维护。

try-with-resources 的基本语法如下:

try (Resource resource = new Resource()) {  
    // 使用资源进行操作  
} // 这里,无论 try 块是否正常结束或抛出异常,资源都将被自动关闭

其中,Resource 是实现了 java.lang.AutoCloseable 接口的类。也就意味着此类必须实现 close() 方法,该方法在资源不再需要时被调用以执行清理操作。注意使用 try-with-resources 语句时,需要将资源类实例放在 try 语句的括号内,由 Java 自动管理资源的关闭。

2.try-with-resources语句示例

现在,我们来看一个具体的例子。假设我们有一个需要从文件中读取数据的程序,我们希望在读取完成后关闭文件资源。在没有 try-with-resources 的情况下,我们的伪代码如下:

File file = new File("demo.txt");  
FileReader reader = null;  
try {  
    reader = new FileReader(file);  
    // 从文件中读取数据  
} catch (IOException e) {  
    // 处理异常  
} finally {  
    // 关闭资源
    if (reader != null) {  
        try {  
            reader.close();  
        } catch (IOException e) {  
            // 处理关闭文件时可能出现的异常  
        }  
    }  
}

很明显,我们要在 finally 块中去关闭资源,这样一来无论程序正常运行还是出现异常都能保证 FileReader 资源的关闭。

我们再使用 try-with-resources,可以简化代码:

try (FileReader reader = new FileReader(new File("demo.txt"))) {  
    // 从文件中读取数据  
} catch (IOException e) {  
    // 处理异常  
}

对比来看,代码是不是简化了很多。在上述代码中,无论 try 块是否正常结束或抛出异常,FileReader 都会被自动关闭。这是通过在 try 块结束后调用 FileReaderclose() 方法实现的。注意,如果你没有捕获可能抛出的异常,那么你可能需要在一个单独的 catch 块中处理它们。

二、JDBC编程中使用try-with-resources

try-with-resources 可以帮助我们自动关闭资源,简化代码。那么在 JDBC 编程中,try-with-resources 主要用于管理数据库的连接操作资源的关闭。这个特性可以确保即使在处理过程中出现异常,数据库的连接操作相关资源也能被正确关闭。

我们还是先来看一下没有使用 try-with-resources 的 JDBC 编程基本示例:

public class TestNoTryWithResources {

    public static void main(String[] args) {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            // 加载数据库驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 创建数据库连接
            connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test_jdbc?serverTimezone=Asia/Shanghai", "root", "root");
            // 创建PreparedStatement对象,预编译SQL语句
            String sql = "select * from teacher where id = ?";
            preparedStatement = connection.prepareStatement(sql);
            // 设置参数
            preparedStatement.setInt(1, 1);
            // 执行SQL查询语句
            resultSet = preparedStatement.executeQuery();
            // 处理查询结果
            while (resultSet.next()) {
                System.out.println(resultSet.getString("name"));
            }
        } catch (ClassNotFoundException | SQLException e) {
            // 异常处理
            e.printStackTrace();
        } finally {
            // 在finally块中关闭资源,确保资源总是被关闭
            try {
                if (resultSet != null) {
                    resultSet.close();
                }
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

如果使用 try-with-resources,我们可以将资源的关闭放在 try 语句括号中,如下所示:

public class TestTryWithResources {

    public static void main(String[] args) {

        String url = "jdbc:mysql://127.0.0.1:3306/test_jdbc?serverTimezone=Asia/Shanghai";
        String user = "root";
        String password = "root";
        String sql = "select * from teacher where id = ?";

        try {
            // 加载数据库驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        // 声明数据库连接、预编译语句资源对象
        try (Connection connection = DriverManager.getConnection(url, user, password);
             PreparedStatement preparedStatement = connection.prepareStatement(sql);){

            // 设置参数
            preparedStatement.setInt(1, 1);
            // 执行SQL查询语句,声明ResultSet资源对象
            try(ResultSet resultSet = preparedStatement.executeQuery();) {
                // 处理查询结果
                while (resultSet.next()) {
                    System.out.println(resultSet.getString("name"));
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,ConnectionPreparedStatementResultSet 都实现了 AutoCloseable 接口,因此它们可以被 try-with-resources 自动关闭。

// Connection继承了AutoCloseable接口
public interface Connection  extends Wrapper, AutoCloseable {}
// PreparedStatement继承了Statement接口
public interface PreparedStatement extends Statement {}
// Statement继承了AutoCloseable
public interface Statement extends Wrapper, AutoCloseable {}
// ResultSet继承了AutoCloseable
public interface ResultSet extends Wrapper, AutoCloseable {}

在 JDBC编程中使用 try-with-resources 语句时,我们将资源的初始化放在 try 语句的括号内,ConnectionPreparedStatement 声明在一个 try 括号中,每条语句,都是 ; 号结尾。这样就可以确保在 try 块执行完毕后这些资源会被自动关闭。对于 try{} 块中的 ResultSet 资源,也需要单独放在一个 try 括号中,这样执行完可以被自动关闭。所以我们学习时要谨记其规则。

当我们在 JDBC 中使用 try-with-resources 语句,大家觉得代码简化了吗?


总结

try-with-resources 特性属于 Java SE 7 模块。更具体地说,这是 Java 7 引入的一个新特性,旨在简化代码,减少资源泄漏。try-with-resources 语句可以自动关闭实现了 AutoCloseable 接口的资源,无论 try 块是否抛出异常。这个特性主要被用于数据库连接、文件操作等需要打开和关闭资源的场景。

需要注意的是:try-with-resources 语句中声明的资源只有在 try 块的括号内才能被正确关闭。如果在 try 块之外声明资源,那么该资源将不会被自动关闭。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程火箭车

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值