写点什么

你还在使用 try-catch-finally 关闭资源?

作者:Java高工P7
  • 2021 年 11 月 11 日
  • 本文字数:1532 字

    阅读完需:约 5 分钟

  • @author hetiantian

  • */


public class Resource implements AutoCloseable {


public void sayHello() {


System.out.println("hello");


}


@Override


public void close() throws Exception {


System.out.println("Resource is closed");


}


}


测试类 CloseResourceIn7.java


/**


  • jdk7 及以后关闭流的方式

  • @author hetiantian

  • */


public class CloseResourceIn7 {


public static void main


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


(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");


}


@Override


public 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");


}


@Override


public 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 Exception


at com.shuwen.Resource.close(Resource.java:15)


at com.shuwen.CloseResourceIn7.errorTest(CloseResourceIn7.java:27)


at com.shuwen.CloseResourceIn7.main(CloseResourceIn7.java:12)

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
你还在使用 try-catch-finally 关闭资源?