你还在使用 try-catch-finally 关闭资源?不太优雅~

2023-12-15 06:38

本文主要是介绍你还在使用 try-catch-finally 关闭资源?不太优雅~,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

点击上方 好好学java ,选择 星标 公众号

重磅资讯、干货,第一时间送达

今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招!

 个人原创100W+访问量博客:点击前往,查看更多

作者:何甜甜在吗

链接:https://juejin.im/post/5b8f9fa05188255c6f1df755

代码一定得写的优雅一点!

你还在使用try-catch-finally关闭资源吗,如果是,那么就有点out了。皮皮甜手把手教你使用JDK7引用的try-with-resource

JDK7之前资源的关闭姿势:

/*** jdk7以前关闭流的方式** @author hetiantian* */
public class CloseResourceBefore7 {private static final String FileName = "file.txt";public static void main(String[] args) throws IOException {FileInputStream inputStream = null;try {inputStream = new FileInputStream(FileName);char c1 = (char) inputStream.read();System.out.println("c1=" + c1);} catch (IOException e) {e.printStackTrace();} finally {if (inputStream != null) {inputStream.close();}}}
}

JDK7及以后关闭资源的正确姿势

try-with-resource Resource的定义:

所有实现了 java.lang.AutoCloseable[1] 接口(其中,它包括实现了 java.io.Closeable[2] 的所有对象),可以使用作为资源。简单Demo进行证实:实现java.lang.AutoCloseable接口的Resource类:

/*** 资源类** @author hetiantian* */
public class Resource implements AutoCloseable {public void sayHello() {System.out.println("hello");}@Overridepublic void close() throws Exception {System.out.println("Resource is closed");}
}

测试类CloseResourceIn7.java

/*** jdk7及以后关闭流的方式** @author hetiantian* */
public class CloseResourceIn7 {public static void main(String[] args) {try(Resource resource = new Resource()) {resource.sayHello();} catch (Exception e) {e.printStackTrace();}}
}

打印结果:

hello
Resource is closed

当存在多个打开资源的时候:资源二Resource2.java

/*** 资源2** @author hetiantian* */
public class Resource2 implements AutoCloseable {public void sayhello() {System.out.println("Resource say hello");}@Overridepublic void close() throws Exception {System.out.println("Resource2 is closed");}
}

测试类CloseResourceIn7.java

/*** jdk7及以后关闭流的方式** @author hetiantian* */
public class CloseResourceIn7 {public static void main(String[] args) {try(Resource resource = new Resource(); Resource2 resource2 = new Resource2()) {resource.sayHello();resource2.sayhello();} catch (Exception e) {e.printStackTrace();}}
}

打印结果:

hello
Resource say hello
Resource2 is closed
Resource is closed

即使资源很多,代码也可以写的很简洁,如果用JDK7之前的方式去关闭资源,那么资源越多,用fianl关闭资源时嵌套也就越多。

那么它的底层原理又是怎样的呢,由皮皮甜独家揭秘优雅关闭资源背后的密码秘密

查看编译的class文件CloseResourceIn7.class:

public class CloseResourceIn7 {public CloseResourceIn7() {}public static void main(String[] args) {try {Resource resource = new Resource();Throwable var2 = null;try {resource.sayHello();} catch (Throwable var12) {var2 = var12;throw var12;} finally {if (resource != null) {if (var2 != null) {try {resource.close();} catch (Throwable var11) {var2.addSuppressed(var11);}} else {resource.close();}}}} catch (Exception var14) {var14.printStackTrace();}}
}

可以发现编译以后生成了try-catch-finally语句块 finally中的var2.addSuppressed(var11);

是不是有疑问?其实这么做是为了处理异常屏蔽的,我们将代码修改一下。

资源Resource.java

/*** 资源类** @author hetiantian* */
public class Resource implements AutoCloseable {public void sayHello() throws Exception {throw new Exception("Resource throw Exception");}@Overridepublic void close() throws Exception {throw new Exception("Close method throw Exception");}
}

两个方法里面都抛出异常

测试类CloseResourceIn7.java

/*** jdk7及以后关闭流的方式** @author hetiantian* */
public class CloseResourceIn7 {public static void main(String[] args) {try {errorTest();} catch (Exception e) {e.printStackTrace();}}private static void errorTest() throws Exception {Resource resource = null;try {resource = new Resource();resource.sayHello();}finally {if (resource != null) {resource.close();}}}
}

打印结果:

java.lang.Exception: Close method throw Exceptionat com.shuwen.Resource.close(Resource.java:15)at com.shuwen.CloseResourceIn7.errorTest(CloseResourceIn7.java:27)at com.shuwen.CloseResourceIn7.main(CloseResourceIn7.java:12)

只打印了最后出现的异常【异常屏蔽】这样会给开发人员排查错误带来一定的困难 我们换成try-with-resource方法实现CloseResourceIn7.java

/*** jdk7及以后关闭流的方式** @author hetiantian* */
public class CloseResourceIn7 {public static void main(String[] args) {try {errorTest();} catch (Exception e) {e.printStackTrace();}}private static void errorTest() throws Exception {try(Resource resource = new Resource()) {resource.sayHello();}}
}

打印信息:

java.lang.Exception: Resource throw Exceptionat com.shuwen.Resource.sayHello(Resource.java:10)at com.shuwen.CloseResourceIn7.errorTest(CloseResourceIn7.java:20)at com.shuwen.CloseResourceIn7.main(CloseResourceIn7.java:12)Suppressed: java.lang.Exception: Close method throw Exceptionat com.shuwen.Resource.close(Resource.java:15)at com.shuwen.CloseResourceIn7.errorTest(CloseResourceIn7.java:21)... 1 more

可以发现,异常信息中多了一个Suppressed的提示,告诉我们这个异常其实由两个异常组成,Close method throw Exception这个异常是被Suppressed【屏蔽】的异常

怎么样,是不是很简单呢,如果学会了话来个在看吧!

参考资料

[1]

java.lang.AutoCloseable: http://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html

[2]

java.io.Closeable: http://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html

最后,给大家准备了一套支付宝、微信支付教程,建议学习一下,拿走不谢!
下载方式1. 首先扫描下方二维码2. 后台回复「A106」即可获取

这篇关于你还在使用 try-catch-finally 关闭资源?不太优雅~的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/495487

相关文章

C语言中联合体union的使用

本文编辑整理自: http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=179471 一、前言 “联合体”(union)与“结构体”(struct)有一些相似之处。但两者有本质上的不同。在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量

Tolua使用笔记(上)

目录   1.准备工作 2.运行例子 01.HelloWorld:在C#中,创建和销毁Lua虚拟机 和 简单调用。 02.ScriptsFromFile:在C#中,对一个lua文件的执行调用 03.CallLuaFunction:在C#中,对lua函数的操作 04.AccessingLuaVariables:在C#中,对lua变量的操作 05.LuaCoroutine:在Lua中,

一份LLM资源清单围观技术大佬的日常;手把手教你在美国搭建「百万卡」AI数据中心;为啥大模型做不好简单的数学计算? | ShowMeAI日报

👀日报&周刊合集 | 🎡ShowMeAI官网 | 🧡 点赞关注评论拜托啦! 1. 为啥大模型做不好简单的数学计算?从大模型高考数学成绩不及格说起 司南评测体系 OpenCompass 选取 7 个大模型 (6 个开源模型+ GPT-4o),组织参与了 2024 年高考「新课标I卷」的语文、数学、英语考试,然后由经验丰富的判卷老师评判得分。 结果如上图所

Vim使用基础篇

本文内容大部分来自 vimtutor,自带的教程的总结。在终端输入vimtutor 即可进入教程。 先总结一下,然后再分别介绍正常模式,插入模式,和可视模式三种模式下的命令。 目录 看完以后的汇总 1.正常模式(Normal模式) 1.移动光标 2.删除 3.【:】输入符 4.撤销 5.替换 6.重复命令【. ; ,】 7.复制粘贴 8.缩进 2.插入模式 INSERT

如何开启和关闭3GB模式

https://jingyan.baidu.com/article/4d58d5414dfc2f9dd4e9c082.html

Lipowerline5.0 雷达电力应用软件下载使用

1.配网数据处理分析 针对配网线路点云数据,优化了分类算法,支持杆塔、导线、交跨线、建筑物、地面点和其他线路的自动分类;一键生成危险点报告和交跨报告;还能生成点云数据采集航线和自主巡检航线。 获取软件安装包联系邮箱:2895356150@qq.com,资源源于网络,本介绍用于学习使用,如有侵权请您联系删除! 2.新增快速版,简洁易上手 支持快速版和专业版切换使用,快速版界面简洁,保留主

如何免费的去使用connectedpapers?

免费使用connectedpapers 1. 打开谷歌浏览器2. 按住ctrl+shift+N,进入无痕模式3. 不需要登录(也就是访客模式)4. 两次用完,关闭无痕模式(继续重复步骤 2 - 4) 1. 打开谷歌浏览器 2. 按住ctrl+shift+N,进入无痕模式 输入网址:https://www.connectedpapers.com/ 3. 不需要登录(也就是

问题-windows-VPN不正确关闭导致网页打不开

为什么会发生这类事情呢? 主要原因是关机之前vpn没有关掉导致的。 至于为什么没关掉vpn会导致网页打不开,我猜测是因为vpn建立的链接没被更改。 正确关掉vpn的时候,会把ip链接断掉,如果你不正确关掉,ip链接没有断掉,此时你vpn又是没启动的,没有域名解析,所以就打不开网站。 你可以在打不开网页的时候,把vpn打开,你会发现网络又可以登录了。 方法一 注意:方法一虽然方便,但是可能会有

加载资源文件失败

背景         自己以前装了一个海康的深度学习算法平台,试用期是一个月,过了一个月之后,因为没有有效注册码或者加密狗的支持了导致无法使用,于是打算卸载掉,在卸载一个软件的时候,无论是使用控制面板还是软件自带的卸载功能,总是卸载不掉,提示“加载资源文件失败”。该软体主要包括以下两部分: 用自带卸载功能卸载的时候分别提示如下:     用控制面板卸载的时候反应很慢,最后也是提示这个

Toolbar+DrawerLayout使用详情结合网络各大神

最近也想搞下toolbar+drawerlayout的使用。结合网络上各大神的杰作,我把大部分的内容效果都完成了遍。现在记录下各个功能效果的实现以及一些细节注意点。 这图弹出两个菜单内容都是仿QQ界面的选项。左边一个是drawerlayout的弹窗。右边是toolbar的popup弹窗。 开始实现步骤详情: 1.创建toolbar布局跟drawerlayout布局 <?xml vers