现在位置: 首页 > Java 教程 > 正文

Java try-with-resources 语句

Java 9 新特性 Java 9 新特性

try-with-resources 是 Java 7 引入的一种简洁的资源管理方式,适用于需要在使用后自动关闭的资源(如文件、数据库连接、网络连接等)。

try-with-resources 能够很容易地关闭在 try-catch 语句块中使用的资源,所谓的资源(resource)是指在程序完成后,必须关闭的对象。

try-with-resources 语句确保了每个资源在语句结束时关闭。

所有实现了 java.lang.AutoCloseable 接口(其中,它包括实现了 java.io.Closeable 的所有对象),可以使用作为资源。

优势:

  • 简化代码:省去手动关闭资源的代码,逻辑更清晰。
  • 减少错误:自动处理资源关闭,避免忘记关闭资源或处理 finally 块中出现的异常。
  • 提升性能:减少资源泄露,节约系统资源。

基本语法

try-with-resources 语法如下:

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

在 try 块中声明的资源会在代码执行完毕后自动关闭,甚至在发生异常时也会安全关闭。

使用 AutoCloseable 接口

为了使资源能够被 try-with-resources 使用,该资源必须实现 AutoCloseable 接口

。AutoCloseable 定义了 close() 方法,系统在 try 块结束后会自动调用这个方法关闭资源。

public class Resource implements AutoCloseable {
    public void doSomething() {
        System.out.println("Using resource...");
    }

    @Override
    public void close() {
        System.out.println("Closing resource...");
    }
}

在使用时,只需将资源放在 try 块中:

try (Resource res = new Resource()) {
    res.doSomething();
} catch (Exception e) {
    e.printStackTrace();
}

输出:

Using resource...
Closing resource...

无论是否发生异常,资源都会在 try 块结束后自动调用 close() 方法。

多个资源管理

try-with-resources 可以同时管理多个资源,只需用分号分隔各资源声明即可:

try (Resource res1 = new Resource();
     Resource res2 = new Resource()) {
    res1.doSomething();
    res2.doSomething();
} catch (Exception e) {
    e.printStackTrace();
}

异常处理

优雅处理异常:当多个资源在 close() 时发生异常,try-with-resources 会将第一个异常抛出,而把其他异常作为 Suppressed Exception 附加。可以通过 Throwable.getSuppressed() 方法获取所有被抑制的异常。

实例

public class ResourceWithException implements AutoCloseable {
    public ResourceWithException() throws Exception {
        System.out.println("Creating resource...");
    }

    public void doSomething() throws Exception {
        System.out.println("Doing something with resource...");
        throw new Exception("Exception in doSomething");
    }

    @Override
    public void close() throws Exception {
        System.out.println("Closing resource...");
        throw new Exception("Exception in close");
    }
}

try (ResourceWithException res = new ResourceWithException()) {
    res.doSomething();
} catch (Exception e) {
    System.out.println("Caught exception: " + e.getMessage());
    for (Throwable suppressed : e.getSuppressed()) {
        System.out.println("Suppressed exception: " + suppressed);
    }
}

输出:

Creating resource...
Doing something with resource...
Closing resource...
Caught exception: Exception in doSomething
Suppressed exception: java.lang.Exception: Exception in close

使用场景

try-with-resources 主要用于需要显式关闭的资源管理,常见的场景包括:

  • 文件操作:FileInputStreamFileOutputStreamBufferedReader 等。
  • 数据库连接:ConnectionStatementResultSet 等。
  • 网络通信:SocketServerSocketHttpURLConnection 等。

例如,使用 try-with-resources 读取文件:

实例

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TryWithResourcesExample {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

实例

try-with-resources 声明在 JDK 9 已得到改进。如果你已经有一个资源是 final 或等效于 final 变量,您可以在 try-with-resources 语句中使用该变量,而无需在 try-with-resources 语句中声明一个新变量。

实例

import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.io.StringReader; public class Tester { public static void main(String[] args) throws IOException { System.out.println(readData("test")); } static String readData(String message) throws IOException { Reader inputString = new StringReader(message); BufferedReader br = new BufferedReader(inputString); try (BufferedReader br1 = br) { return br1.readLine(); } } }

输出结果为:

test

以上实例中我们需要在 try 语句块中声明资源 br1,然后才能使用它。

在 Java 9 中,我们不需要声明资源 br1 就可以使用它,并得到相同的结果。

实例

import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.io.StringReader; public class Tester { public static void main(String[] args) throws IOException { System.out.println(readData("test")); } static String readData(String message) throws IOException { Reader inputString = new StringReader(message); BufferedReader br = new BufferedReader(inputString); try (br) { return br.readLine(); } } }

执行输出结果为:

test

在处理必须关闭的资源时,使用 try-with-resources 语句替 代try-finally 语句。 生成的代码更简洁,更清晰,并且生成的异常更有用。 try-with-resources 语句在编写必须关闭资源的代码时会更容易,也不会出错,而使用 try-finally 语句实际上是不可能的。

Java 9 新特性 Java 9 新特性