加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java7里try-with-resources分析--转

发布时间:2020-12-14 06:22:51 所属栏目:Java 来源:网络整理
导读:原文地址:http://blog.csdn.net/hengyunabc/article/details/18459463 这个所谓的try-with-resources,是个语法糖。实际上就是自动调用资源的close()函数。和里的with语句差不多。 例如: div class="dp-highlighter bg_java" div class="bar" div class="t

原文地址:http://blog.csdn.net/hengyunabc/article/details/18459463

这个所谓的try-with-resources,是个语法糖。实际上就是自动调用资源的close()函数。和里的with语句差不多。

例如:

<div class="dp-highlighter bg_java">
<div class="bar">
<div class="tools">
[java]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/hengyunabc/article/details/18459463#" target="_blank">view plain<span data-mod="popu_168"><span data-mod="popu_168">?<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/hengyunabc/article/details/18459463#" target="_blank">copy

?
  1. ????
  2. ????}??

可以看到try语句多了个括号,而在括号里初始化了一个BufferedReader。

这种在try后面加个括号,再初始化对象的语法就叫try-with-resources。

实际上,相当于下面的代码(其实略有不同,下面会说明):

<div class="dp-highlighter bg_java">
<div class="bar">
<div class="tools">
[java]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/hengyunabc/article/details/18459463#" target="_blank">view plain<span data-mod="popu_168"><span data-mod="popu_168">?<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/hengyunabc/article/details/18459463#" target="_blank">copy

?
  1. ????BufferedReader?br?=?
  2. ????????
  3. ????????
  4. }??

很容易可以猜想到,这是编绎器自动在try-with-resources后面增加了判断对象是否为null,如果不为null,则调用close()函数的的字节码。

只有实现了java.lang.AutoCloseable接口,或者java.io.Closable(实际上继随自java.lang.AutoCloseable)接口的对象,才会自动调用其close()函数。

有点不同的是.io.Closable要求一实现者保证close函数可以被重复调用。而AutoCloseable的close()函数则不要求是幂等的。具体可以参考Javadoc。

下面从编绎器生成的字节码来分析下,try-with-resources到底是怎样工作的:

<div class="dp-highlighter bg_java">
<div class="bar">
<div class="tools">
[java]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/hengyunabc/article/details/18459463#" target="_blank">view plain<span data-mod="popu_168"><span data-mod="popu_168">?<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/hengyunabc/article/details/18459463#" target="_blank">copy

?
  1. ????
  2. ????????????System.out.println(tryStudy);??
  3. ????}??
  4. ????
  5. }??

TryStudy实现了AutoCloseable接口,下面来看下test函数的字节码:

<div class="dp-highlighter bg_java">
<div class="bar">
<div class="tools">
[java]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/hengyunabc/article/details/18459463#" target="_blank">view plain<span data-mod="popu_168"><span data-mod="popu_168">?<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/hengyunabc/article/details/18459463#" target="_blank">copy

?
  1. ??TRYCATCHBLOCK?L0?L1?L2???
  2. ?L5??
  3. ??ACONST_NULL??
  4. ??ACONST_NULL??
  5. ?L3??
  6. ??DUP??
  7. ?()V??
  8. ??ASTORE?
  9. ??LINENUMBER?
  10. ??ALOAD?
  11. ?L1??
  12. ??ALOAD?
  13. ??ALOAD?
  14. ??GOTO?L6??
  15. ?FRAME?FULL?[java/lang/Throwable?java/lang/Throwable?TryStudy]?[java/lang/Throwable]??
  16. ??ALOAD?
  17. ??ALOAD?
  18. ?L7??
  19. ??ALOAD?
  20. ?L4??
  21. ??ASTORE?
  22. ??IFNONNULL?L8??
  23. ??ASTORE?
  24. ?L8??
  25. ??ALOAD?
  26. ??IF_ACMPEQ?L9??
  27. ??ALOAD?
  28. ?L9??
  29. ??ALOAD?
  30. ?L6??
  31. ?FRAME?CHOP?
  32. ??LOCALVARIABLE?tryStudy?LTryStudy;?L0?L7?
  33. ??MAXLOCALS?=?

从字节码里可以看出,的确是有判断tryStudy对象是否为null,如果不是null,则调用close函数进行资源回收。

再仔细分析,可以发现有一个Throwable.addSuppressed的调用,那么这个调用是什么呢?

其实,上面的字节码大概是这个样子的(当然,不完全是这样的,因为汇编的各种灵活的跳转用Java是表达不出来的):

<div class="dp-highlighter bg_java">
<div class="bar">
<div class="tools">
[java]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/hengyunabc/article/details/18459463#" target="_blank">view plain<span data-mod="popu_168"><span data-mod="popu_168">?<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/hengyunabc/article/details/18459463#" target="_blank">copy

?
  1. ????TryStudy?tryStudy?=?
  2. ????????tryStudy?=?
  3. ????}
  4. ????????????
  5. ????????????}
  6. ????????????????
  7. ????????}??
  8. ????}??

有点晕是吧,其实很简单。使用了try-with-resources语句之后,有可能会出现两个异常,一个是try块里的异常,一个是调用close函数里抛出的异常。

当然,平时我们写代码时,没有关注到。一般都是再抛出close函数里的异常,前面的异常被丢弃了。

如果在调用close函数时出现异常,那么前面的异常就被称为Suppressed Exceptions,因此Throwable还有个addSuppressed函数可以把它们保存起来,当用户捕捉到close里抛出的异常时,就可以调用Throwable.getSuppressed函数来取出close之前的异常了。

总结:

使用try-with-resources的语法可以实现资源的自动回收处理,大大提高了代码的便利性,和mutil catch一样,是个好东东。

用编绎器生成的字节码的角度来看,try-with-resources语法更加高效点。

java.io.Closable接口要求一实现者保证close函数可以被重复调用,而AutoCloseable的close()函数则不要求是幂等的。

参考:

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读