try-with-resources 是 Java 7 引入的一种简洁的资源管理方式,适用于需要在使用后自动关闭的资源(如文件、数据库连接、网络连接等)。
try-with-resources 能够很容易地关闭在 try-catch 语句块中使用的资源,所谓的资源(resource)是指在程序完成后,必须关闭的对象。
try-with-resources 语句确保了每个资源在语句结束时关闭。
所有实现了 java.lang.AutoCloseable 接口(其中,它包括实现了 java.io.Closeable 的所有对象),可以使用作为资源。
优势
简化代码:省去手动关闭资源的代码,逻辑更清晰。
减少错误:自动处理资源关闭,避免忘记关闭资源或处理 finally 块中出现的异常。
提升性能:减少资源泄露,节约系统资源。
基础使用 try (ResourceType resource = new ResourceType ()) { } catch (ExceptionType e) { }
使用 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 块结束后自动调用 close() 方法。
try (Resource res = new Resource ()) { res.doSomething(); } catch (Exception e) { e.printStackTrace(); }
Using resource... Closing resource...
多个资源管理 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 声明在 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(); } } }