点击上方“方志朋”,选择“设为星标”

回复”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 关闭资源?相关推荐

  1. Java正常关闭资源的方式

    在实际开发中,经常需要在程序中打开一些物理资源,如数据库连接.网络连接.磁盘文件等,打开这些物理资源之后必须显式关闭,否则将会引起资源泄漏. JVM的垃圾回收机制不会回收这些资源,垃圾回收机制属于Ja ...

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

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 作者:何 ...

  3. 哈哈,咱们团队早就不用try-catch-finally关闭资源了!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 代码一定得写的优雅一点! 你还在使用try-catch-final ...

  4. try-with-resource:自动地关闭资源

    目录 一.资源关闭背景 二.JDK7之前的资源关闭方式 三.JDK7及其之后的资源关闭方式 3.1 try-with-resource语法 3.2 实现原理 3.3 异常抑制 3.4 try-with ...

  5. Effective java 系列之更优雅的关闭资源-try-with-resources

    背景: 在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制,如果我们不在 ...

  6. Java如何实现文件拷贝操作和如何正确关闭资源

    使用字节流完成文件的拷贝: 使用字节输入流(FileInputStream)将源文件中的数据读进来,同时使用字节输出流(FileOutputStream)将读进来的数据写到目标文件中,即一边读一边写, ...

  7. 优雅地关闭资源,try-with-resource语法和lombok@Cleanup

    资源的打开就需要对应的关闭,但我们常会忘记关闭资源,或在多处代码关闭资源感到杂乱,有没有简洁的关闭方法呢? 自动关闭资源类需实现AutoCloseable接口和配合try-with-resource语 ...

  8. 为DbHelper工具类添加关闭资源的方法 jdbc 20210412_212728.mp4

    为DbHelper工具类添加关闭资源的方法 jdbc 给dbhelper工具类添加关闭资源的方法 接收所有的资源对象 然后关闭他们 代码 import java.sql.*;public class ...

  9. finally中关闭资源

    对finally中关闭资源是否还要使用try...catch老是感到迷惑,现在存个例子,省的忘了 1 public StringBuilder readTxtFile(File file){ 2 St ...

最新文章

  1. Liunx下的日志清理shell脚本实战之日志备份
  2. 有关函数模板和类模板的说法
  3. ext store 数据修改_Go 数据存储篇(一):基于内存存储实现数据增删改查功能...
  4. 一文揭秘阿里实时计算Blink核心技术:如何做到唯快不破?
  5. CMake 编译 OpenCV 项目,不是编译OpenCV, 用了之后才知道CMake也太好用了。
  6. Java多线程系列(六):深入详解Synchronized同步锁的底层实现
  7. 使用主题文件(包含CSS文件)时遇到的问题
  8. 将你一张表的值覆盖_精准度可达亚米级,山东“北斗一张网”向社会免费开放...
  9. 信息学奥赛一本通 1180 | 1946:【09NOIP普及组】分数线划定 | OpenJudge NOI 1.10 05 | 洛谷 P1068 [NOIP2009 普及组] 分数线划定
  10. 全志a33android编译,编译lichee - 全志A33的环境搭建
  11. 内部控制检查和内部控制审计的区别
  12. utf-8编码引起js输出中文乱码的解决办法
  13. Defining custom settings in Odoo
  14. 我的世界服务器如何开无限小号,实操神技能,微信能“无限”开小号?
  15. Linux dns劫持程序,linux的dns被劫持(解决方案)
  16. 记一次小米手机安装Google Play(其他手机类似)
  17. 前端三刺客---CSS
  18. 网页未连接到互联网,代理服务器出现问题
  19. java 利用继承和多态设计三角形,圆矩形
  20. 面对不同种类的处理结果——result type=

热门文章

  1. 《JavaScript高级程序设计》读书笔记【一】
  2. think in Java 第五章之垃圾回收类型
  3. metasploit-smb扫描获取系统信息
  4. 整理Simple.Data使用方法
  5. java中数组的一些笔记
  6. 如何用Asp判断你的网站的虚拟物理路径
  7. 刻意练习:LeetCode实战 -- Task22. 二叉树的中序遍历
  8. 【MATLAB】矩阵运算之矩阵分解
  9. java ee不能运行_Java9+移除 Java EE,导致我的 groovy 脚本无法运行
  10. 达摩院年终预测重磅出炉:AI for Science 高居榜首,2022 十大科技趋势!