java中的try-with-resource语法

这篇具有很好参考价值的文章主要介绍了java中的try-with-resource语法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

java的世界千奇百怪。。。当我甩出如下代码段,不知阁下如何应对?

try(A a=new A()){
    和a变量无关的业务代码块
}

没错,这就是“臭名昭著”的try-with-resource语法,乍一看让人不知所云,其实它和try-finally的下述代码等价

A a=new A()
try{
    //业务代码块
}finally{
    a.close();
}

本质上就是当使用 try-with-resources 语句块来处理实现了 AutoCloseable 接口的资源时,Java 编译器会在生成的字节码中进行特殊处理。编译器会自动在 try 块结束时插入 finally 块,并在 finally 块中调用 close() 方法来关闭资源。

try-with-resources语法

try-with-resources 语句是一个 Java 7 引入的语法结构,用于自动关闭实现了 AutoCloseableCloseable 接口的资源。它的语法形式如下:

try (resource_declaration) {
    // 使用资源的代码块
} catch (ExceptionType e) {
    // 异常处理逻辑
}

try-with-resources 语句中,resource_declaration 部分用于声明和初始化一个或多个资源对象。这些资源对象必须实现 AutoCloseableCloseable 接口。

try 代码块中,可以使用这些资源对象进行操作。当 try 代码块执行结束时,不论是正常结束还是发生异常,都会自动调用资源对象的 close() 方法来关闭资源。

如果同时声明了多个资源对象,可以使用分号 ; 分隔它们。

那么,它和try-finally语句有什么区别呢?

和try-finally的关系

很明显,try-with-resource语法相对于try-finally语法来说,隐式的调用了资源对象的close方法,语法更简洁,其次,让我们看看如下代码块:

@Test
public void testException(){

    try{
        throw new CustomException("代码块内的业务异常");
    }finally {
        throw new CustomException("finally中的资源释放异常");
    }
}

运行上面的代码,你将会得到如下异常:

java中的try-with-resource语法

模仿上述代码,看看在try-with-resource语法中又会怎样

先创建一个类MyAutoClose

@Slf4j
public class MyAutoClose implements AutoCloseable {
    @Override
    public void close() throws Exception {
        log.info("自动关闭");
        throw new CustomException("close方法异常");
    }
}

运行如下单元测试

@Test
public void testAutoClose() {
    try (MyAutoClose autoClose = new MyAutoClose()) {
        throw new CustomException("业务异常");
    } catch (Exception e) {
        log.error("", e);
    }
}

得到如下异常

java中的try-with-resource语法

综合两种结果来看,可以看到同样的逻辑,业务和finally都是抛出了异常,但是抛出的异常却不一样:在try-finally语句块中,抛出的是finally中的异常,在try-with-resource语句块中,抛出的是业务的异常,而且异常中还携带了close方法关闭时抛出的异常信息。

谁好谁坏,自行体会。

try-with-resources的本质

再进一步细想一下,为啥两种方式逻辑基本一样,但是抛出的异常却不一样?

try-finally代码块很直观,try-with-resource代码块在编译成字节码文件的时候却被编译期“魔改”了,上文提到过

......Java 编译器会在生成的字节码中进行特殊处理。编译器会自动在 try 块结束时插入 finally 块,并在 finally 块中调用 close() 方法来关闭资源。

那只需要通过反编译看下class文件就可以了

java中的try-with-resource语法

再回想一下它原来长什么样子

@Test
public void testAutoClose() {
    try (MyAutoClose autoClose = new MyAutoClose()) {
        throw new CustomException("业务异常");
    } catch (Exception e) {
        log.error("", e);
    }
}

亲妈都认不出来了。。。

我将反编译后的真正代码分成了四部分,并标记在了图上

  1. 外层异常try-catch块尝试捕获初始化资源异常
  2. 里层try-catch块尝试捕获业务执行异常
  3. 业务try-catch块捕获到异常,直接抛出
  4. finally块判定是否发生了业务异常:如果发生了业务异常,而且close方法执行也发生了异常,则将close方法发生的异常附加业务异常中;如果未发生业务异常,则直接执行close方法,这时候如果发生了异常,直接抛出的就是finally块中的异常了。

总结下,实际上是如下形式

try{
    //初始化资源
    try{
        //业务代码执行
    }catch(Exceptin e){
        //捕获的业务异常,抛出业务异常
    }finally{
        //执行close方法,并判定在不同情况下的异常信息
    }
}catch(Exception e){
    //捕获的资源初始化异常
}

结论:使用try-with-resource很明显比使用try-finally块要更好一些,它能准确捕获业务异常;但是try-finally块也有不可替代的使用场景,比如资源类未实现AutoCloseable接口的时候

最后,欢迎关注我的博客原文:https://blog.kdyzm.cn/post/179

END.文章来源地址https://www.toymoban.com/news/detail-748870.html

到了这里,关于java中的try-with-resource语法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++ try-catch语法分析与应用

    通过前面的学习,我们了解了try-catch语法的基本使用。但是,C++提供的异常处理机制很全面,下面再具体分析。 发生异常的时候,我们可以主动抛出一个异常,所以,使用throw抛出一个异常。异常可以是一个数值,字符,或者表达式。 抛出的异常可以有try-catch语句捕获。tr

    2024年02月16日
    浏览(44)
  • 【JVM】Java堆 :深入理解内存中的对象世界

    人不走空                                                                            目录         🌈个人主页:人不走空       💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 ​编辑 什么是Java堆? 作用和特点 1. 存储对象实例 2. 垃圾收集 3. 对象

    2024年01月19日
    浏览(51)
  • Python 异常处理 try-except,else,finally, with 语句的区别

    在日常编写程序时,难免会遇到错误,有的是由于疏忽造成的语法错误,有的是程序内部隐含逻辑问题造成的数据错误,还有的是程序运行时与系统的规则冲突造成的系统错误,等等。 总的来说,编写程序时遇到的错误可大致分为 2 类,分别为语法错误和运行时错误。 Pyth

    2023年04月08日
    浏览(38)
  • 【JavaSE】Java基础语法(十三):Java 中的集合(十分全面)

    List (对付顺序的好帮⼿): 存储的元素是有序的、可重复的。 Set (注重独⼀⽆⼆的性质): 存储的元素是⽆序的、不可重复的。 Queue (实现排队功能的叫号机): 按特定的排队规则来确定先后顺序,存储的元素是有序的、可重复的。 Map (⽤ key 来搜索的专家): 使⽤键值对(key-value)存

    2024年02月10日
    浏览(42)
  • JSON 基本语法以及在Java 中的使用

    JSON(JavaScript Object Notation)是一种轻量级的数据交互格式。它去除了所有 JavaScript 执行代码,只保留 JavaScript 的对象格式。 它基于 ECMAScript (欧洲计算机协会制定的 js 规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。 JSON适合表示层次结构,JSON采用键

    2024年01月23日
    浏览(45)
  • 【前后端对接迷惑问题】无法加载响应数据:No resource with given identifier found

    开发对接过程中遇到的问题,希望对你有帮助!

    2024年02月11日
    浏览(50)
  • 【JavaSE】Java基础语法(三十七):Java 中的 String 类(源码级别)

    String 表示 字符串类型,属于 引用数据类型 。Java 中 String 是 不可变 的。 在 Java 当中 双引号 括起来的字符串,是直接存储在“方法区”的“字符串常量池”当中的。 源码: 源码: 源码: 源码: 源码: 源码: 源码: 源码: https://blog.csdn.net/qq_44715943/article/details/116308837

    2024年02月06日
    浏览(49)
  • axios无法加载响应数据:no data found for resource with given identifier

    美好的、令人遐想的日落黄昏里,出现了诡异的bug! 老师上课的时候,不好好听听,不仔细看!那么花了那么多时间找bug问题~翻了好多方案,还未解决,然后遇到了我,这个大冤种就是你(也包括我*~*)!!!  猜想了好多种方案,其中一度被pass的解决方案既然是原因!!

    2024年02月03日
    浏览(52)
  • Error creating bean with name ‘kafkaTemplate‘ defined in class path resource

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name \\\'org.springframework.boot.autoconfigure.kafka.KafkaAnnotationDrivenConfiguration\\\': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.kafka.Kafka

    2024年02月07日
    浏览(58)
  • 出现 Try run Maven import with -U flag (force update snapshots) 的解决方法

    在配置Maven依赖信息的时候,出现如下问题:

    2024年02月15日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包