企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# Java 7 中的`try-with-resources` > 原文: [https://howtodoinjava.com/java7/try-with-resources/](https://howtodoinjava.com/java7/try-with-resources/) [**Java 7**](//howtodoinjava.com/category/java-7/ "java 7 features") 为懒惰的 Java 开发人员带来了一些非常好的特性。`try-with-resource`是这样的特性之一,它可以减少代码行,并使代码更健壮。 在本教程中,我将讨论有关此特性的内容。 ![java 7 features](https://img.kancloud.cn/f9/81/f981c69f6997d396c90a7f924bdbb181_478x405.png "java 7 features") ```java Sections in this post: The old way of resource cleanup (Before java 7) The new fancy way with try-with-resources (syntax example) How actually it works? Adding functionality to custom resources Final notes ``` ## 资源清除的旧方法(在 Java 7 之前) 我们长期以来一直在这样做。 例如从文件系统读取文件。 代码可能看起来有所不同,但流程如下例所示: ```java public class ResourceManagementBeforeJava7 { public static void main(String[] args) { BufferedReader br = null; try { String sCurrentLine; br = new BufferedReader(new FileReader("C:/temp/test.txt")); while ((sCurrentLine = br.readLine()) != null) { System.out.println(sCurrentLine); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (br != null) br.close(); } catch (IOException ex) { ex.printStackTrace(); } } } } ``` 这些类型的代码在具有大量 IO 操作的应用程序代码库中非常常见。 `try`和`catch`块中的代码本质上很重要,并且具有一些特定于应用程序的逻辑。 但是,`finally`块呢? 在大多​​数情况下,最后只是复制粘贴了`finally`块,目的是通过关闭它们来避免损坏资源。 当您有 3-4 个这样的资源要在单个`finally`块中关闭时,这些`finally`块看起来更难看。 当我们知道时,您是否认为这些`finally`块不必要地存在,我们必须以任何方式关闭资源而没有任何异常情况? Java 7 通过`try-with-resources`特性解决了这个问题。 ## 使用`try-with-resources`的新方法(语法示例) 现在看看在 Java 7 中打开和关闭资源的新方法。 ```java public class ResourceManagementInJava7 { public static void main(String[] args) { try (BufferedReader br = new BufferedReader(new FileReader("C:/temp/test.txt"))) { String sCurrentLine; while ((sCurrentLine = br.readLine()) != null) { System.out.println(sCurrentLine); } } catch (IOException e) { e.printStackTrace(); } } } ``` 有两件事需要密切注意: 1. 文件资源(`BufferedReader`)以特殊方式在`try`块中打开(在小括号内)。 2. `finally`块完全消失了。 最后但并非最不重要的一点是,代码看起来很漂亮且易于阅读。 很好,对吗? 但是实际上是如何工作的? ## 实际上如何运作? 在 Java 7 中,我们有一个新的超接口[**`java.lang.AutoCloseable`**](https://docs.oracle.com/javase/7/docs/api/java/lang/AutoCloseable.html "AutoCloseable")。 此接口有一种方法: ```java void close() throws Exception; ``` Java 文档建议将此接口**实现在不再需要它时必须关闭的任何资源上**。 当我们在特殊的`try-with-resource`块中打开任何此类`AutoCloseable`资源时,在`try`块完成后, **JVM 会对在`try()`块**中初始化的所有资源调用此`close()`方法。 例如,`BufferedReader`已实现`close()`方法文件如下: ```java public void close() throws IOException { synchronized (lock) { if (in == null) return; in.close(); in = null; cb = null; } } ``` 由于上述方法定义,当 JVM 调用此方法时,所有基础流或 IO 资源都将关闭。 ## 向自定义资源添加功能 好吧,这是一个很好的资源清理设计。 但是它仅适用于 JDK 本机类吗? 没有。 您也可以将其用于自定义资源。 例如,我在以下代码中创建了一个自定义资源: ```java public class CustomResource implements AutoCloseable { public void accessResource() { System.out.println("Accessing the resource"); } @Override public void close() throws Exception { System.out.println("CustomResource closed automatically"); } } ``` 现在,我将在示例代码中使用它: ```java public class TryWithCustomResource { public static void main(String[] args) { try(CustomResource cr = new CustomResource()) { cr.accessResource(); } catch (Exception e) { e.printStackTrace(); } } } Putput in console: Accessing the resource CustomResource closed automatically ``` 控制台中的输出清楚地证明,`try`块完成后,资源将自动关闭。 ## 最后注意事项 这就是 Java 7 中使用`try-with-resources`进行自动资源管理的全部内容。让我们逐点记下重点: * 在 Java 7 之前,我们必须使用`finally`块来清理资源。 `finally`块不是强制性的,但是清理资源是为了防止系统损坏。 * 使用 Java 7,无需显式的资源清理。 它是自动完成的。 * 在`try-with-resources`块(`try(…){…}`)中初始化资源时完成自动资源清理。 * 由于新接口`AutoCloseable`而发生清除。 `try`块完成后,JVM 将立即调用其`close`方法。 * 如果要在自定义资源中使用此特性,则必须实现`AutoCloseable`接口。 否则程序将无法编译。 * 您不应在代码中调用`close()`方法。 这应该自动称为 JVM。 手动调用它可能会导致意外结果。 **祝您学习愉快!**