开关资源新方法:Try- with-resources
JDK7新特性:Try- with-resources
try-with-resources 是 JDK 7中引入的一种新的异常处理机制,它主要用于自动管理资源,能够很容易地关闭在 try-catch 语句块中使用的资源。确保资源在不再需要时能够被正确关闭。这种机制简化了资源管理,使得资源的释放更加安全和可预测。
resource:是指在程序完成后,必须关闭的对象(例如:文件资源File、IO流、Socket、ServerSocket网络对象、数据库链接对象等)。try-with-resources 语句确保了每个资源在语句结束时关闭。
普通开关资源方法
class Myresources1 implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("资源1关闭方法执行");
        throw new Exception("资源1关闭异常");
    }
}
class Myresources2 implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("资源2关闭方法执行");
        throw new Exception("资源2关闭异常");
    }
}
为了避免在代码执行中出现异常,使用try-catch-finally进行异常捕获
        Myresources1 myresources1 =null;
        Myresources2 myresources2 = null;
        try{
            myresources1 = new Myresources1();
            myresources2 = new Myresources2();
            System.out.println("hello");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (myresources1!=null){
                try {
                    myresources1.close();
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    if (myresources2!=null){
                        try {
                            myresources2.close();
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

Try- with-resources控制资源语法:
    try(Myresources1 myresources1 = new Myresources1();
        Myresources2 myresources2 = new Myresources2();){
           System.out.println("hello");
        //int a = 2/0;
       }catch (Exception e){
           e.printStackTrace();
       }

处理规则
- 凡是实现了AutoCloseable或者Closeable接口的类,在try()里声明该类实例的时候,在try结束后,close方法都会被调用。不管是否出现异常(int i=1/0会抛出异常),try()里的实例都会被调用close方法
 
- 越晚声明的对象,会越早被close掉。
- try结束后自动调用的close方法,这个动作会早于finally里调用的方法。


异常抑制问题
Myresources1 myresources1 = null;
        try{
            myresources1 = new Myresources1();
            //算数异常
            System.out.println(10/0);
        }finally {
            if (myresources1!=null)
                myresources1.close();
        }
//myresources1类
class Myresources1 implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("资源1关闭方法执行");
        throw new Exception("资源1关闭异常");
    }
}
运行异常打印:

此时可以看到,异常只打印了close()方法的异常,而 10/0 的异常被抑制了
        try(Myresources1 myresources1 = new Myresources1();){
            System.out.println(10/0);
        }
运行异常打印: <br 当一个异常被抛出的时候,可能有其他异常因为该异常而被抑制住,从而无法正常抛出。这时可以通过
<br 当一个异常被抛出的时候,可能有其他异常因为该异常而被抑制住,从而无法正常抛出。这时可以通过addSuppressed() 方法把这些被抑制的方法记录下来,然后被抑制的异常就会出现在抛出的异常的堆栈信息中,可以通过 getSuppressed() 方法来获取这些异常。这样做的好处是不会丢失任何异常,方便我们进行调试。
反编译代码:

        Myresources1 myresources1 = new Myresources1();
        Throwable var2 = null;
        try {
            System.out.println(10 / 0);
        } catch (Throwable var11) {
            var2 = var11;
            throw var11;
        } finally {
            if (myresources1 != null) {
                //判断程序运行时是否出现异常
                if (var2 != null) {	//出现异常
                    try {
                        myresources1.close();
                    } catch (Throwable var10) {
                        var2.addSuppressed(var10);	//把close()发生的异常添加为抑制异常
                    }
                } else {	//程序运行时无异常
                    myresources1.close();
                }
            }
        }
循环打印抑制异常
 try(Myresources1 myresources1 = new Myresources1();){
            System.out.println(10/0);
        }catch (Exception e){
            e.printStackTrace();
            Throwable[] suppressed = e.getSuppressed();
            for (Throwable t : suppressed){
                t.printStackTrace();
            }
        }
运行结果:

使用场景
try-with-resources 语法适用于任何需要自动管理资源关闭,以防止资源泄漏的场景。
简单粗暴点就是,ctrl点进去看当前资源,只要当前资源实现了AutoCloseable或者Closeable接口就可以用。但是,具体使用还要根据要实现的业务场景来决定。
不适合的场景:
- 资源未实现AutoCloseable或Closeable接口:
如果资源没有实现 AutoCloseable 或 Closeable 接口,那么它就不能在 try-with-resources 语句中被自动关闭。这种情况下,仍然需要手动关闭资源,或者使用其他机制来确保资源的正确关闭。
- 资源需要在try块外部使用:
try-with-resources 语句中的资源在 try块执行完毕后会自动关闭,因此在 try块外部无法访问这些资源。如果资源需要在 try 块外部被使用,那么就不能使用 try-with-resources语句来管理这些资源。
- 需要精细控制资源关闭时机:
在某些情况下,开发者可能需要根据特定的逻辑或条件来决定何时关闭资源,而不是在 try 块结束时立即关闭。try-with-resources 语句无法提供这种精细的控制,因此在这些场景下可能不适用。
- 资源关闭可能抛出异常且需要特殊处理:
虽然 try-with-resources  语句会尝试关闭资源,并捕获在关闭过程中抛出的异常,但这些异常通常会被抑制(suppressed),而不是直接抛出。如果开发者需要特别处理这些关闭异常,或者需要将这些异常与 try 块中抛出的其他异常进行区分,那么 try-with-resources  可能不是最佳选择。
- 资源需要在多个try块中共享:
如果一个资源需要在多个 try块中被共享和使用,那么使用 try-with-resources 语句可能会变得复杂或不可行。因为每个 try-with-resources  语句都会尝试在结束时关闭其声明的资源,这可能会导致资源在需要时已经被关闭。
- 资源关闭逻辑复杂:
如果资源的关闭逻辑非常复杂,或者需要在关闭前执行一些特定的操作(如回滚事务、释放锁等),那么使用 try-with-resources语句可能不足以满足需求。在这些情况下可能需要编写更复杂的finally块来确保资源的正确关闭。综上所述,try-with-resources  语句虽然是一种强大的资源管理机制,但它并不适用于所有场景。在选择是否使用 try-with-resources  时,开发者需要根据具体的需求和资源的特点来做出决策。
优点:
- 简化资源管理代码:无需显式地在 finally块中编写资源关闭的代码,减少了代码量和出错的可能性。
- 提高代码可读性:使资源的管理更加清晰和直观,让开发者能够更专注于业务逻辑。
- 确保资源及时关闭:即使在 try块中发生异常,资源也会被自动关闭,避免了资源泄漏的风险。
- 支持多个资源:可以同时管理多个资源,它们都会按照声明的反顺序被正确关闭。
缺点:
- 支持的资源类型有限:并非所有的类都可以作为 - try-with-resources的资源,只有实现了- AutoCloseable或- Closeable接口的类才行。
- 性能考虑: - 虽然 - try-with-resources在大多数情况下对性能的影响可以忽略不计,但在极端情况下(例如:在性能敏感的应用程序中频繁地打开和关闭大量资源),它可能会引入一些额外的开销。这是因为- try-with-resources语句在编译时会生成额外的代码来管理资源的关闭。
- 对在 - try()中声明的对象不能重新赋值
     FileWriter fw = new FileWriter("a.txt");
     fw = new FileWriter("e:/b.txt");
		try(FileWriter fw = new FileWriter("a.txt")){
            fw = new FileWriter("b.txt");	//报错
        }catch (Exception e){
            e.printStackTrace();
        }
//此时会编译出错:The resource is1 of a try-with-resources statement cannot be assigned
官方文档:
It is a compile-time error if final appears more than once as a modifier for each variable declared in a resource specification.
A variable declared in a resource specification is implicitly declared final (§4.12.4) if it is not explicitly declared final.
在资源规范中声明的每个变量,如果 final 作为修饰符出现不止一次,则属于编译时错误。
在资源规范中声明的变量,如果没有显式地声明为 final,则隐式地声明为 final(§4.12.4)。
try-with-resource中声明的变量会隐式的加上final 关键字,所以无法再进行赋值
总结:
try-with-resources 的优点通常大于缺点,在大多数情况下,它是一种更安全、简洁和可靠的资源管理方式。具体的使用方式根据业务场景决定,但是一般情况下,处理必须关闭的资源时,始终有限考虑使用 try-with-resources,而不是 try–catch-finally。前者产生的代码更加简洁、清晰,产生的异常信息也更靠谱。
开关资源新方法:Try- with-resources的更多相关文章
- 视频资源下载方法[download video resources]
		笔者做视频时钟分析,需要用到大量特殊的视频,如何获取需要的视频是一个问题? 以下载NBA视频为例: Tools:①腾讯视频软件 (自行下载) ②批处理文件(下文会给出代码) convert.bat ... 
- Java获取/resources目录下的资源文件方法
		Web项目开发中,经常会有一些静态资源,被放置在resources目录下,随项目打包在一起,代码中要使用的时候,通过文件读取的方式,加载并使用: 今天总结整理了九种方式获取resources目录下文件 ... 
- [转] 中国压缩传感资源(China Compressive Sensing Resources)
		昨天查压缩感知的资料,无意间看到一位浙大女神Rachel Zhang的博客,果断关注了.我感觉应该向她好好学习.下面转自她的CSDN博客.网址是http://blog.csdn.net/abcjenn ... 
- 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法
		若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ... 
- 在C#中如何使用资源的方法
		总结一个在C#中如何使用资源的方法:一:使用本地文件1.将本地要加入的资源文本(视频,图片,文本或其它)加入项目,比如我们现在加入一个up.bmp的图片到项目中,且放在文件夹Resources下面,2 ... 
- iOS5中UIViewController的新方法
		iOS5中UIViewController的新方法 前言 在苹果的 WWDC2011 大会视频的<Session 101 - What's New in Cocoa> 和<Sessi ... 
- Unity3D获取资源的方法整理:
		在使用Unity3D做项目时,获取资源的方法大致分为两种.一种是通过写代码的方式,在程序运行时,自动获取资源:一种是通过手动拖拽的方式进行获取.不管是什么类型的资源都能通过这两种方式获得,下面拿图片资 ... 
- SQL Server中解决死锁的新方法介绍
		SQL Server中解决死锁的新方法介绍 数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过SQL Server 2005, 现在似乎有了一种新的解决办法. 将下面的 ... 
- RegisterUserFunc为测试对象添加新方法或重写已有方法
		QTP中为了提高扩展性,提供了一个为测试对象添加一个新的自定义方法,或者重写测试对象已有的方法的函数RegisterUserFunc,在此给大家分享一下. RegisterUserFunc:为测试对象 ... 
- angular学习笔记(二十八-附1)-$resource中的资源的方法
		通过$resource获取到的资源,或者是通过$resource实例化的资源,资源本身就拥有了一些方法,$save,$delete,$remove,可以直接调用来保存该资源: 比如有一个$resour ... 
随机推荐
- Windows10(or windows11) Hyper-V 创建虚拟交换机后宿主机上传速度变特别慢的问题解决
			问题 我在我的win11上启用了Hyper-v,装了个虚拟机跑了个CentOS7.6,为了让centos和宿主机通信在同个网段搞了个桥接网络,网络环境如下 然后我测试一个文件上传功能的时候发现网络上传 ... 
- C# SM2算法 加密,解密,签名,验签
			最近时间在整SM2算法,在网上看到不少代码,基本都是使用BouncyCastle库,现在这个版本算比较好的拿来分享给大家. 首先引入包 Portable.BouncyCastle 完整代码见Gitee ... 
- QT6设置应用程序图标
			准备好一个ico格式的图标, 放到源码文件中, 比如放在 resources/logo.ico 在源码目录中新建一个icon.rc的文件, 内容如下: IDI_ICON1 ICON DISCARDAB ... 
- PAT-甲级-1007
			一.看题,https://www.patest.cn/contests/pat-a-practise/1007 其实,也是一顿暴力,但是最后一个测试点会运行超时,最开始,计算一段区间的值的总和的时候, ... 
- 在Linux驱动中使用proc子系统
			在Linux驱动中使用proc子系统 背景 proc文件系统是个简单有用的东东:驱动创建一个proc虚拟文件,应用层通过读写该文件,即可实现与内核的交互. 本文适用于3.10以后的内核,v3.10以前 ... 
- k8s学习总结之各组件功能及作用的详细介绍
			K8S集群架构: 一个K8S集群是由两大部分组成: Master节点和Node节点 一.Master节点主要包括API Server.Scheduler.Controller manager.etcd ... 
- 全国产RK3568J + FPGA的PCIe、FSPI通信实测数据分享!
			测试数据汇总 案例 时钟频率 理论速率 测试结果 FSPI通信案例 150MHz 71.53MB/s 读速率:67.452MB/s 写速率:52.638MB/s PCIe通信案例 100MHz 803 ... 
- TI AM64x工业核心板硬件说明书(双核ARM Cortex-A53 + 单/四核Cortex-R5F + 单核Cortex-M4F,主频1GHz)
			1 硬件资源 创龙科技SOM-TL64x是一款基于TI Sitara系列AM64x双核ARM Cortex-A53 + 单/四核Cortex-R5F + 单核Cortex-M4F设计 ... 
- UNR #7 Day2 T1 火星式选拔题解
			放一个比赛链接 先考虑打完暴力后 \(k = 1\) 的特殊性质. 当队列容量为 \(1\) 时,队中的人 \(i\) 会被第一个满足 \(i \leq j\) 且 \(b_i \leq a_j\) ... 
- python3 json.dumps(OrderDict类型) 报错:TypeError: Object of type datetime is not JSON serializable
			chatgpt给出的解决方案, 在json.dumps()函数调用中传入default参数来指定如何处理datetime对象 import json from datetime import date ... 
