你还在使用 try-catch-finally 关闭资源?
点击上方“方志朋”,选择“设为星标”
回复”666“获取新整理的面试文章
作者:何甜甜在吗
链接: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关闭资源时嵌套也就越多。最近写的这篇:写了个全局变量的bug,也推荐看下。
那么它的底层原理又是怎样的呢,由皮皮甜独家揭秘优雅关闭资源背后的密码秘密
查看编译的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
热门内容:API 面试四连杀:接口如何设计?安全如何保证?签名如何实现?防重如何实现
为什么 SQL 语句不要过多的 join?
前后端分离 Spring Boot + Vue 开发网易云&QQ音乐(附源码)!fastjson到底做错了什么?为什么会被频繁爆出漏洞?
用 float 存储金额,老板说损失从工资里扣!最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)ノ♡
你还在使用 try-catch-finally 关闭资源?相关推荐
- Java正常关闭资源的方式
在实际开发中,经常需要在程序中打开一些物理资源,如数据库连接.网络连接.磁盘文件等,打开这些物理资源之后必须显式关闭,否则将会引起资源泄漏. JVM的垃圾回收机制不会回收这些资源,垃圾回收机制属于Ja ...
- 你还在使用 try-catch-finally 关闭资源?不太优雅~
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 作者:何 ...
- 哈哈,咱们团队早就不用try-catch-finally关闭资源了!
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 代码一定得写的优雅一点! 你还在使用try-catch-final ...
- try-with-resource:自动地关闭资源
目录 一.资源关闭背景 二.JDK7之前的资源关闭方式 三.JDK7及其之后的资源关闭方式 3.1 try-with-resource语法 3.2 实现原理 3.3 异常抑制 3.4 try-with ...
- Effective java 系列之更优雅的关闭资源-try-with-resources
背景: 在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制,如果我们不在 ...
- Java如何实现文件拷贝操作和如何正确关闭资源
使用字节流完成文件的拷贝: 使用字节输入流(FileInputStream)将源文件中的数据读进来,同时使用字节输出流(FileOutputStream)将读进来的数据写到目标文件中,即一边读一边写, ...
- 优雅地关闭资源,try-with-resource语法和lombok@Cleanup
资源的打开就需要对应的关闭,但我们常会忘记关闭资源,或在多处代码关闭资源感到杂乱,有没有简洁的关闭方法呢? 自动关闭资源类需实现AutoCloseable接口和配合try-with-resource语 ...
- 为DbHelper工具类添加关闭资源的方法 jdbc 20210412_212728.mp4
为DbHelper工具类添加关闭资源的方法 jdbc 给dbhelper工具类添加关闭资源的方法 接收所有的资源对象 然后关闭他们 代码 import java.sql.*;public class ...
- finally中关闭资源
对finally中关闭资源是否还要使用try...catch老是感到迷惑,现在存个例子,省的忘了 1 public StringBuilder readTxtFile(File file){ 2 St ...
最新文章
- Liunx下的日志清理shell脚本实战之日志备份
- 有关函数模板和类模板的说法
- ext store 数据修改_Go 数据存储篇(一):基于内存存储实现数据增删改查功能...
- 一文揭秘阿里实时计算Blink核心技术:如何做到唯快不破?
- CMake 编译 OpenCV 项目,不是编译OpenCV, 用了之后才知道CMake也太好用了。
- Java多线程系列(六):深入详解Synchronized同步锁的底层实现
- 使用主题文件(包含CSS文件)时遇到的问题
- 将你一张表的值覆盖_精准度可达亚米级,山东“北斗一张网”向社会免费开放...
- 信息学奥赛一本通 1180 | 1946:【09NOIP普及组】分数线划定 | OpenJudge NOI 1.10 05 | 洛谷 P1068 [NOIP2009 普及组] 分数线划定
- 全志a33android编译,编译lichee - 全志A33的环境搭建
- 内部控制检查和内部控制审计的区别
- utf-8编码引起js输出中文乱码的解决办法
- Defining custom settings in Odoo
- 我的世界服务器如何开无限小号,实操神技能,微信能“无限”开小号?
- Linux dns劫持程序,linux的dns被劫持(解决方案)
- 记一次小米手机安装Google Play(其他手机类似)
- 前端三刺客---CSS
- 网页未连接到互联网,代理服务器出现问题
- java 利用继承和多态设计三角形,圆矩形
- 面对不同种类的处理结果——result type=