Java try-with-resources 介绍

jupiter
2026-03-14 / 0 评论 / 2 阅读 / 正在检测是否收录...

Java try-with-resources 介绍

1. 什么是 try-with-resources?

try-with-resources 是 Java 7 引入的一个特性,用于自动管理资源(如文件流、数据库连接、网络连接等)。它确保每个资源在语句结束时自动关闭,无需显式编写 finally 块。

优点:

  1. 代码简洁:减少样板代码
  2. 安全可靠:自动确保资源关闭
  3. 异常处理更完善:保留原始异常,关闭异常作为抑制异常
  4. 可读性更好:清晰地看到资源声明和使用范围

2. 基本语法

try (ResourceType resource = new ResourceType()) {
    // 使用资源的代码
} catch (ExceptionType e) {
    // 异常处理
}

3. 工作原理

  • 资源必须实现 AutoCloseableCloseable 接口
  • 在 try 块结束后,资源会按照声明的相反顺序自动关闭
  • 资源关闭操作在 finally 块之前执行

4. 支持多资源

try (FileInputStream fis = new FileInputStream("input.txt");
     FileOutputStream fos = new FileOutputStream("output.txt")) {
    
    byte[] buffer = new byte[1024];
    int length;
    while ((length = fis.read(buffer)) > 0) {
        fos.write(buffer, 0, length);
    }
} catch (IOException e) {
    e.printStackTrace();
}

5. 异常处理机制

try-with-resources 提供了更优雅的异常处理机制:

public class ResourceExample {
    static class Resource1 implements AutoCloseable {
        public void use() throws Exception {
            throw new Exception("异常发生在使用资源时");
        }
        
        @Override
        public void close() throws Exception {
            throw new Exception("异常发生在关闭资源时");
        }
    }
    
    public static void main(String[] args) {
        try (Resource1 r1 = new Resource1()) {
            r1.use();
        } catch (Exception e) {
            System.out.println("捕获的异常: " + e.getMessage());
            Throwable[] suppressed = e.getSuppressed();
            System.out.println("被抑制的异常数量: " + suppressed.length);
        }
    }
}

6. 实际应用示例

文件操作示例

import java.io.*;

public class FileCopyExample {
    public static void copyFile(String source, String dest) {
        // 传统方式
        /*
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(source);
            fos = new FileOutputStream(dest);
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) > 0) {
                fos.write(buffer, 0, length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) fis.close();
                if (fos != null) fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        */
        
        // try-with-resources 方式
        try (FileInputStream fis = new FileInputStream(source);
             FileOutputStream fos = new FileOutputStream(dest)) {
            
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) > 0) {
                fos.write(buffer, 0, length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

数据库连接示例

import java.sql.*;

public class DatabaseExample {
    public static void queryDatabase() {
        String url = "jdbc:mysql://localhost:3306/mydb";
        String user = "root";
        String password = "password";
        
        // 自动管理 Connection, Statement, ResultSet
        try (Connection conn = DriverManager.getConnection(url, user, password);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
            
            while (rs.next()) {
                System.out.println(rs.getString("username"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

8. Java 9 增强功能

Java 9 允许在 try-with-resources 中使用 effectively final 的变量:

public class Java9Example {
    public static void main(String[] args) throws Exception {
        // Java 9 之前
        try (FileReader reader1 = new FileReader("file1.txt");
             FileReader reader2 = new FileReader("file2.txt")) {
            // 使用资源
        }
        
        // Java 9 及之后
        FileReader reader1 = new FileReader("file1.txt");
        FileReader reader2 = new FileReader("file2.txt");
        // reader1 和 reader2 必须是 effectively final
        try (reader1; reader2) {
            // 使用资源
        }
    }
}

9. 注意事项

  • 资源类必须实现 AutoCloseableCloseable 接口
  • 资源在 try 块结束后自动关闭,无论是否发生异常
  • 多个资源按声明相反顺序关闭
  • 如果有多个异常,只有第一个异常被抛出,其他异常被抑制
0

评论 (0)

打卡
取消