try-with-resources 工作原理

概述

try-with-resources 是 Java 7 引入的一种语法糖,用于简化资源管理,确保在使用资源后自动关闭它们。它是 try 语句的增强形式,可以在资源使用完毕后自动调用它们的 close() 方法,从而避免资源泄漏。

但这有个前提:就是资源类必须直接或间接实现了 java.lang.AutoCloseable ,详细信息请参阅资源定义板块。

基本语法

单个资源写法
try (ResourceType resource = new ResourceType()) {// 使用资源
} catch (ExceptionType e) {// 处理异常
}
多个资源写法
try (ResourceType resource1 = new ResourceType(); ResourceType resource2 = new ResourceType()) {// 使用资源
}

资源定义

任何实现了 java.lang.AutoCloseable 接口的类都可以作为 try-with-resources 语句的资源。AutoCloseable 接口只有一个方法:

public interface AutoCloseable {void close() throws Exception;
}

另一个常用的接口是 java.io.Closeable,它是 AutoCloseable 的子接口,专门用于 I/O 相关的资源,如 InputStreamReader

例如:Socket就实现了Closeableclose()方法

public synchronized void close() throws IOException {synchronized(closeLock) {if (isClosed())return;if (created)impl.close();closed = true;}
}

所以,用户也可以自定义类来实现AutoCloseable接口,实现close()方法后,即可在try-with-resources种使用。


CloseableAutoCloseable

  • AutoCloseable 是一个通用接口,可以被任何需要在使用后关闭的资源实现。
  • Closeable 继承自 AutoCloseable,并专门为 I/O 相关的资源设计。它的 close() 方法只能抛出 IOException,而 AutoCloseableclose() 方法可以抛出任何异常。

AutoCloseable 的设计更通用,而 Closeable 则专门用于处理 I/O 异常。

常见的实现了 Closeable 接口的 I/O 资源类

输入流和输出流读取和写入其他 I/O 类
java.io.InputStreamjava.io.Readerjava.io.RandomAccessFile
java.io.OutputStreamjava.io.Writerjava.nio.channels.FileChannel
java.io.FileInputStreamjava.io.FileReaderjava.util.zip.ZipFile
java.io.FileOutputStreamjava.io.FileWriter
java.io.BufferedInputStreamjava.io.BufferedReader
java.io.BufferedOutputStreamjava.io.BufferedWriter
java.io.DataInputStreamjava.io.PrintWriter
java.io.DataOutputStream

注:更多实现类信息请参考最后的补充信息板块

工作原理

资源声明和初始化

try 语句中声明的资源会被自动初始化,并且该初始化的资源是被自动关闭的。多个资源可以用分号分隔:

try (ResourceType resource1 = new ResourceType(); ResourceType resource2 = new ResourceType()) {// 使用资源
}
资源关闭顺序

多个资源按照它们声明的顺序关闭,即后声明的先关闭。例如,以上代码中的 resource2 会先于 resource1 被关闭。

自动关闭的实现

try 语句块执行完毕后(无论是否抛出异常),try-with-resources 语句会自动调用资源的 close() 方法。这个过程是通过编译器生成的字节码实现的,并不需要程序员显式编写关闭资源的代码。

例如,以下代码:

try (MyResource resource = new MyResource()) {// 使用资源
}

会被编译成类似于以下的字节码:

MyResource resource = null;
try {resource = new MyResource();// 使用资源
} catch (Exception e) {// 处理异常throw e;
} finally {if (resource != null) {try {resource.close();} catch (Exception e) {// 处理关闭资源时的异常}}
}

异常处理

try-with-resources 对异常处理也进行了改进。当 try 块中的代码和 close 方法都抛出异常时,close 方法抛出的异常将被抑制,真正的异常是 try 块中的异常。被抑制的异常可以通过 Throwable.getSuppressed() 方法获取。

例如:

try (MyResource resource = new MyResource()) {throw new Exception("Exception in try block");
} catch (Exception e) {// e 是 "Exception in try block"Throwable[] suppressed = e.getSuppressed();// suppressed[0] 是 close() 方法抛出的异常
}

总结

try-with-resources 提供了一种简洁、安全的资源管理方式,主要优点包括:

  • 简化资源管理:自动关闭资源,避免显式的 finally 代码块。
  • 减少代码冗余:不需要显式编写 close() 方法的调用。
  • 改进异常处理:更好地管理多个异常,避免遗漏资源关闭导致的资源泄漏。

这种语法糖极大地提高了代码的可读性和可靠性,是 Java 7 以来一个重要的语法改进。

补充

所有已知 Closeable 实现类

AbstractInterruptibleChannel, AbstractSelectableChannel, AbstractSelector, AsynchronousFileChannel, AsynchronousServerSocketChannel, AsynchronousSocketChannel, AudioInputStream, BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter, ByteArrayInputStream, ByteArrayOutputStream, CharArrayReader, CharArrayWriter, CheckedInputStream, CheckedOutputStream, CipherInputStream, CipherOutputStream, DatagramChannel, DatagramSocket, DataInputStream, DataOutputStream, DeflaterInputStream, DeflaterOutputStream, DigestInputStream, DigestOutputStream, FileCacheImageInputStream, FileCacheImageOutputStream, FileChannel, FileImageInputStream, FileImageOutputStream, FileInputStream, FileOutputStream, FileReader, FileSystem, FileWriter, FilterInputStream, FilterOutputStream, FilterReader, FilterWriter, Formatter, ForwardingJavaFileManager, GZIPInputStream, GZIPOutputStream, ImageInputStreamImpl, ImageOutputStreamImpl, InflaterInputStream, InflaterOutputStream, InputStream, InputStream, InputStream, InputStreamReader, JarFile, JarInputStream, JarOutputStream, LineNumberInputStream, LineNumberReader, LogStream, MemoryCacheImageInputStream, MemoryCacheImageOutputStream, MLet, MulticastSocket, ObjectInputStream, ObjectOutputStream, OutputStream, OutputStream, OutputStream, OutputStreamWriter, Pipe.SinkChannel, Pipe.SourceChannel, PipedInputStream, PipedOutputStream, PipedReader,PrintStream, PrintWriter, PrivateMLet, ProgressMonitorInputStream, PushbackInputStream, PushbackReader, RandomAccessFile, Reader, RMIConnectionImpl, RMIConnectionImpl_Stub, RMIConnector, RMIIIOPServerImpl, RMIJRMPServerImpl, RMIServerImpl, Scanner, SelectableChannel, Selector, SequenceInputStream, ServerSocketChannel, Socket, SocketChannel, SSLServerSocket, SSLSocket, StringBufferInputStream, StringReader, StringWriter, URLClassLoader, Writer, ZipFile, ZipInputStream, ZipOutputStream

所有已知 AutoCloseable 实现类

AbstractInterruptibleChannel, AbstractSelectableChannel, AbstractSelector, AsynchronousFileChannel, AsynchronousServerSocketChannel, AsynchronousSocketChannel, AudioInputStream, BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter, ByteArrayInputStream, ByteArrayOutputStream, CharArrayReader, CharArrayWriter, CheckedInputStream, CheckedOutputStream, CipherInputStream, CipherOutputStream, DatagramChannel, DatagramSocket, DataInputStream, DataOutputStream, DeflaterInputStream, DeflaterOutputStream, DigestInputStream, DigestOutputStream, FileCacheImageInputStream, FileCacheImageOutputStream, FileChannel, FileImageInputStream, FileImageOutputStream, FileInputStream, FileLock, FileOutputStream, FileReader, FileSystem, FileWriter, FilterInputStream, FilterOutputStream, FilterReader, FilterWriter, Formatter, ForwardingJavaFileManager, GZIPInputStream, GZIPOutputStream, ImageInputStreamImpl, ImageOutputStreamImpl, InflaterInputStream, InflaterOutputStream, InputStream, InputStream, InputStream, InputStreamReader, JarFile, JarInputStream, JarOutputStream, LineNumberInputStream, LineNumberReader, LogStream, MemoryCacheImageInputStream, MemoryCacheImageOutputStream, MLet, MulticastSocket, ObjectInputStream, ObjectOutputStream, OutputStream, OutputStream, OutputStream, OutputStreamWriter, Pipe.SinkChannel, Pipe.SourceChannel, PipedInputStream, PipedOutputStream, PipedReader、 PipedWriter, PrintStream, PrintWriter, PrivateMLet, ProgressMonitorInputStream, PushbackInputStream, PushbackReader, RandomAccessFile, Reader, RMIConnectionImpl, RMIConnectionImpl_Stub, RMIConnector, RMIIIOPServerImpl, RMIJRMPServerImpl, RMIServerImpl, Scanner, SelectableChannel, Selector, ServerSocket, ServerSocketChannel, Socket, SocketChannel, SSLServerSocket, SSLSocket, StringBufferInputStream, StringReader, StringWriter, URLClassLoader, Writer, XMLDecoder, XMLEncoder, ZipFile, ZipInputStream, ZipOutputStream

(注:补充信息来源自 Jdk1.8 API 文档)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/27486.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java多线程面试重点-2

16.Synchronized关键字加在静态方法和实例方法的区别? 修饰静态方法,是对类进行加锁(Class对象),如果该类中有methodA和methodB都是被Synch修饰的静态方法,此时有两个线程T1、T2分别调用methodA()和methodB()&#x…

对于千兆变压器(Gigabit Transformer)的设计

对于千兆变压器(Gigabit Transformer)的设计,以下是一些关键方面的详细说明: 1. **频率特性:** 千兆变压器需要能够在高频率下工作,通常在1 GHz以上。为了确保良好的性能,设计中需要选择合适的…

热门开源项目推荐:智谱GLM-4-9B和ChatGLM3-6B

目录 热门开源项目推荐:智谱GLM-4-9B和ChatGLM3-6B 1.引言 1.1 开源文化简介 1.2 开源项目的重要性 1.3 博客目的和读者价值 2.什么是开源项目? 2.1 开源定义 2.2 开源许可证类型 2.3 开源社区的作用 3.为什么程序员应该关注开源项目&#xff…

如何在Ubuntu 22.04中还原默认终端:解决无法打开终端的问题

我之前安装了xterm和新的Python,无法打开ubuntu自带的gnome-terminalle 。 终端应用崩溃: 试着通过其他方式打开终端,例如按下 CtrlAltT。 尝试使用其他终端模拟器,例如 xterm、konsole 或 gnome-terminal。可以通过 AltF2 然后…

IDM究竟有哪些优势?一探究竟,揭开下载利器的神秘面纱

在当今互联网信息爆炸的时代,下载工具已经成为我们日常生活中不可或缺的一部分。Internet Download Manager(IDM)以其强大的功能和高效的性能,赢得了广大用户的青睐。那么,IDM究竟有哪些优势使其在众多下载工具中脱颖而…

整蛊软件/插件使用方法与配置步骤~

今天出一期整蛊软件的使用方法与配置步骤 很多人在使用整蛊软件的时候 想自己添加更多的玩法内容 但是还不知道如何去配置 这期给大家出一下图文教程步骤 基本上也是软件的功能介绍使用方式~ 案例可扫码查看 第一步:打开软件输入卡密登录: 卡密费用&…

最经济实惠的通配符SSL证书是哪款?

网络安全已成为企业和个人网站运营者关注的焦点。SSL证书作为确保数据传输安全的关键工具,其重要性不言而喻。特别是通配符SSL证书,因其能够为一个主域名及其所有子域名提供统一的安全保护,而受到广泛欢迎。但面对市场上众多的SSL证书品牌和价…

[大模型]Qwen2-7B-Instruct 接入 LangChain 搭建知识库助手

环境准备 在 autodl 平台中租赁一个 3090 等 24G 显存的显卡机器,如下图所示镜像选择 PyTorch–>2.1.0–>3.10(ubuntu20.04)–>12.1 接下来打开刚刚租用服务器的 JupyterLab,并且打开其中的终端开始环境配置、模型下载和运行 demo。 pip 换源…

mysql中社区版如何杀死锁

在MySQL中,特别是社区版,当遇到锁问题时,你可能需要杀死锁定资源的进程来解决问题。以下是一些步骤和相关信息,用于在MySQL中杀死锁定的进程: 查看当前进程: 首先,你需要查看当前MySQL中的所有…

One能聊天接入百度千帆AppBuilder

One能聊天介绍:基于ChatGPT实现的微信小程序,适配H5和WEB端。包含前后端,支持打字效果输出流式输出,支持AI聊天次数限制,支持分享增加次数等功能One能聊天开源地址:https://github.com/oldinaction/ChatGPT-MPOne能聊天演示环境:可关注【阿壹族】公众号,并回复【One能聊…

MySQL复制机制详解:主从复制与GTID复制的配置与管理

引言: MySQL复制是MySQL数据库的一项重要功能,它允许数据从一个MySQL数据库服务器(被称为主服务器)复制到一个或多个MySQL数据库服务器(被称为从服务器)。主要目的是为了实现数据冗余和备份,提高数据的可用性和读取性能。 主从复制(Master-Slave Replication)是最常…

12_YouOnlyLookOnce(YOLOv3)新一代实时目标检测技术

1.1 回顾V1和V2 V1:05_YouOnlyLookOnce(YOLOV1)目标检测领域的革命性突破-CSDN博客 V2:07_YouOnlyLookOnce(YOLOv2)Better,Faster,Stronger-CSDN博客 1.2 简介 YOLOv3(You Only Look Once version 3)是…

spring boot jwt 实现用户登录完整java

spring boot jwt 实现用户登录完整java 登录校验逻辑 用户登录的校验逻辑分为三个主要步骤,分别是校验验证码,校验用户状态和校验密码,具体逻辑如下 前端发送username、password、captchaKey、captchaCode请求登录。判断captchaCode是否为…

ubuntu 20.04禁止自动更新内核驱动、显卡驱动(使用命令行)

本文目录 一、禁止更新内核1.1 查看当前内核1.2 查看安装的内核1.3 根据需求,使用hold参数禁止固定内核1.4 查询被锁定不更新软件包的状态 二、禁止更新显卡驱动2.1 查看安装的显卡驱动2.2 查看详细的详细的显卡信息2.3 禁止显卡驱动更新2.4 查询显卡是否设置成功 前…

618网络机顶盒哪个牌子好?内行盘点网络机顶盒排行榜

因工作原因每天都在跟各种类型的网络机顶盒打交道,最近超多朋友问我网络机顶盒哪个牌子好,不知道如何挑选网络机顶盒,我将要分享目前最值得入手的网络机顶盒排行榜,想买网络机顶盒可以看看以下这些品牌: ★泰捷WEBOX 6…

【力扣】目标和

一、题目描述 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 或 - ,然后串联起所有整数,可以构造一个 表达式 : 例如,nums [2, 1] ,可以在 2 之前添加 ,在 1 之前添加 - &a…

鸿蒙开发HarmonyOS Next 网络框架retrofit 封装 viemodel使用

新手刚开始学习harmonyos开发,之前搞安卓开发习惯使用retrofit,结果在三方库中还真搜到了,然后就模拟学习一下。有不对的地方请指点一下。新手新手 oh-package.json5 引入库 retofit 需要使用2.0.1-rc.0 以上版本,修复了retrofit发送网络请…

变压器绕组内部故障的Simulink仿真

​利用变压器纵联差动保护的Simulink仿真模型是无法进行变压器绕组内部故障仿真的。为了解决这一问题,可将图中的三相变压器模型改变为三个单相变压器 , 在变压器属性框中选中 “三绕组变压器” (Three windings Transformer), 从而构造出一个一次绕组, 两个二次绕组…

《Windows API每日一练》4.2 设备环境

在第三章我们已经使用设备环境句柄在窗口客户区绘图了。在图形输出设备(比如屏幕或者打印机)上绘制图形,必须首先获取设备环境,即DC的句柄。当 Windows把这个句柄交给你的程序,Windows同时也就给予你使用这个设备的权限…

MySQL学习——管理复制源服务器的SQL语句

管理复制源服务器的语句,主要是指数据库环境中主从复制(master-slave replication)或主主复制(master-master replication)的设置。这些设置用于在多个数据库服务器之间同步数据,以实现高可用性、备份或负载…