今天要讨论的话题是jdk7中引进的try-with-resource。当看到这个名字的第一时间,不清楚的朋友肯定会猜到这个新玩意跟try有点关系,但为什么还要with resource,即带上所谓的“资源”呢?

先谈谈什么是资源

什么是资源呢?我们可以举一个最简单的例子,钱就是资源!人人都想要的东西就是资源,反之,人人都讨厌的东西就是垃圾。

所以此时,资源有一个明显的特征,即抢手!

在软件开发中,资源同样也是那些“抢手货”,最明显的例子就是内存了。电脑中所有的程序都依赖于内存才能运行,谁抢到的内存多,谁运行的就快(相对而言),给用户的体验就更好。所以为了解决软件们对内存的竞争,编程语言越来越注重对内存的管理,而多数程序员也都知道,从C++到Java就明显基于这一考虑。

释放资源的控制权

C++到Java的演变,有一个大的变化就是内存的释放权从程序员自身变成了JVM,如此可以极大降低内存泄露的风险,而jdk7中引进的try-with-resource,正是基于同样的考虑,将资源的释放权从程序员的手中拿回来,然后强制进行释放。

所以,try-with-resource带来的最大的变化,就是资源释放的强制性,同时也给编程提供了一定的便利性。

那么try-with-resource中,资源的释放行为是如何定义的呢?这里就不得不提一下AutoCloseable接口了!通过其名字我们就能猜测出,这个接口专注于“关闭”这一行为,而且关闭还具备自动化的特性,果不其然,这个接口里只定义了一个方法,方法的名字正是close()。

到这里应该猜到了吧,从JDK7开始,对资源的定义可以简单的描述为:

凡是实现了AutoCloseable接口的类的实例都可以被看作是一种资源,程序员们只要自定义close()的实现,完成对资源的释放(其实你爱干嘛干嘛,不但不释放资源,你再申请其它的资源都没事)就OK了,至于close()方法的具体调用,try-with-resource为你负责!

TRY-WITH-RESOURCE长什么样

说了这么多废话,不如下图来的实在,直接给出了try-with-resource的用法:

各位看到上图之后会发现,try-with-resource跟传统的try-catch-finally的用法基本一致,只不过try后面直接跟了一对括号(),然后括号里面的表达式即为try-with-resource表达式。

重点一来了:try-with-resource是一种表达式,而不是类似于try-catch-finally的控制类语法!

既然是一种表达式,那就很好理解了,括号里你可以写多个子表达式,它们之间使用经典的也是默认的也是其它表达式采用的分隔符--分号进行分隔就可以了。

我们再看一下上图中的ResourceA和ResourceB是个什么玩意:

ResourceA和ResourceB都继承自BaseResource,而BaseResource实现了AutoCloseable接口,按照JDK7以后的说法,ResourceA和ResourceB都是一种资源了,所以:

重点二来了:try-with-resource表达式里声明的对象必须是一种资源,即必须要直接或间接的实现了AutoCloseable接口!

如果try-with-resource表达式里声明的对象不是一种资源,编译都不让你通过!

TWR和TCF,“你们不一样?”

先看一个对比的例子,即同样功能的代码,先采用try-with-resource的方式写一遍,再使用经典的try-catch-finally写一遍,其中的差异,一目了然!

第一,也是最重要的一点,TWR中,需要释放的资源不用在finally块中进行手工释放了,因为TWR“好自为之”了。一方面让代码更加简洁,另一方面,也避免了“手残”而导致的资源忘关闭。

第二,TWR表达式中声明的变量,其生命周期在try代码块中依然有效,而TCF模式下,多数需要在try之前进行声明,以便在catch和finally代码块中可以继续访问该变量。

以上两点呢,就是眼见为实的好处。

到目前为止,可能会有朋友会问,try-with-resource表达式可以继续使用catch和finally进行相关的操作吗?答案是当然可以!再重申一遍,try-with-resource只是一种表达式,不是控制性的语法!以前的try-catch-finally怎么用,现在还是怎么用,只是有一点需要明确:

catch和finally的代码块是在资源的close方法执行之后才会执行!

TWR的“小坑坑”

这里的小坑坑其实就是“异常压制”。所谓异常压制就是当一块代码有多个地方同时抛出异常时,某个地方抛出的异常不会被catch到。针对try-with-resource而言,会被压制的异常就是资源即AutoCloseable的close方法抛出的异常,资源在创建以及try代码块中抛出的异常不会被压制。

这种压制机制其实很好理解,因为close方法不是程序员手工调用的,所以程序员就不会注意close方法抛出的异常,顺其自然,也就没有“责任”去捕获这些异常了。

结束语

try-with-resource这功能挺好的,建议所有需要操作资源的代码都使用TWR表达式,如此一来可以“跟上潮流”。

最后附上本次课题的测试代码,有兴趣的朋友可以自己测试,也只有自己测试之后,才能更好的理解。但凡有任何指教,请一定评论出来,因为大家好才是真的好!

---------关于作者----------

Java开发人员,在今日头条开有视频专栏《Java高级加油站》,头条号名称跟知乎名称相同,想看视频专栏的朋友可以去搜索关关注!

-------------------------------------------------------------------------

java 及时释放内存_Java里可以自动释放的不只是内存,只要是“资源”,都可以自动释放!轻松加愉快!...相关推荐

  1. java并发 cpu高_java高并发核心要点|系列5|CPU内存伪共享

    上节提到的:伪共享,今天我们来说说. 那什么是伪共享呢? 这得从CPU的缓存结构说起.以下如图,CPU一般来说是有三级缓存,1 级,2级,3级,越上面的,越靠近CPU的,速度越快,成本也越高.也就是说 ...

  2. java堆内存和堆外内存_Java堆空间,本机堆和内存问题

    java堆内存和堆外内存 最近,我正在和一个朋友讨论为什么Java进程使用的内存比启动Java进程时设置的最大堆多. 代码创建的所有Java对象都是在Java堆空间内创建的,其大小由-Xmx选项定义. ...

  3. java string占用内存_Java中String到底占用多大的内存空间?

    写在前面 对于Java中的String类占用多大的内存空间这个问题,是最近面试中问的比较多的一个问题.很多小伙伴的回答的都不是很正确,有说不占空间的,有说1个字节的,有说2个字节的,有说3个字节的,有 ...

  4. java怎么保存文件_java里数据怎么保存到硬盘或TXT文件里去

    import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import java.io.IOExcepti ...

  5. java 数组降序_Java里的数组降序

    Java升序容易,降序不易. 基本类型不能降序,至少要是包装类. 升序使用Arrays.sort() 降序要么使用Collections.reverse,要么实现Comparator接口 import ...

  6. java中scanner类_Java里Scanner 类

    package com.xuexi; import java.util.Scanner; public class ScannerDemo1 { //通过 Scanner 类的 nextLine() ...

  7. java 恶汉和懒汉_java里的 懒汉和恶汉模式-----讲解

    ------------java中的恶汉模式 public void Test{ private static Test inte = new Test(); // 内部自己创建好实例,私有属性(不建 ...

  8. java显示日历 插件_JAVA里 怎么用日期控件 在Grid里显示这个月的1-31号

    展开全部 日期类Date Java在日期类中封装了有关日期和时62616964757a686964616fe59b9ee7ad9431333236613432间的信息,用户可以通过调用相应的方法来获取 ...

  9. java中的 限制_java里如何限制输入的字符

    初学java,近来做了个类似于qq的聊天登录框,其他都还好,只是"帐户"一栏不知道怎么限制输入字母和符号(帐户由纯数字组成),程序代码如下,望编程高手能够帮我加几行代码来限制帐.. ...

  10. java static变量销毁_JAVA里static 变量在程序执行结束后是否被消毁

    static变量是属于类的,一般情况下,程序执行结束后,类所占空间会被回收, static变量自然就被销毁了. 如下所示: public class StaticVar{ public static ...

最新文章

  1. MPB:邓晔、王尚等-​环境样本中的细菌总量测定—流式细胞法
  2. 部署laravel项目
  3. Paste模块的世界
  4. with as 用法_介词with用法
  5. 在Mono/Linux上使用PerformanceCounter
  6. 解决Mac下安装新版本IDEA无法启动
  7. C++中private成员变量和protect成员变量的区别
  8. C++学习之路 | PTA乙级—— 1033 旧键盘打字 (20 分)(精简)
  9. Canal Mysql binlog 同步至 Hbase ES
  10. 原生语言开发web版万岳网校源码 v2.2.0
  11. Spring Boot学习笔记:Spring Boot核心配置
  12. Android中用文件初始化sqlite 数据库(二)
  13. centos7.4 kubeadm安装Kubernetes 1.14.1 集群
  14. (四)语音识别测试案例
  15. 医院药品管理系统源码 HIS系统源码
  16. 拼音模糊查询+java,jquery拼音模糊查询
  17. 关于vs应用程序无法正确启动问题
  18. Java GUI+MySQL 银行管理系统初级(课程设计)
  19. linux java 缓存服务器,linux服务器缓存环境memcached筹建及应用(java)
  20. iOS 获取照相机实时预览图片

热门文章

  1. 小飞升值记——(13)
  2. 信息系统项目管理师考试重点和难点分析
  3. 什么是 DNS 泛洪?
  4. Python count() 方法
  5. 软件测试DAY3-执行用例
  6. 团队作业6——展示博客(alpha阶段)
  7. 【Opencv实战】美颜模式,开启:美颜功能都这么强大了嘛?(群魔乱舞.jpg)
  8. 硬件基本概念-模拟电子电路
  9. flickr网站用到的php技术
  10. netbeans使用教程_IDE:5个最喜欢的NetBeans功能