0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Java的异常原理

科技绿洲 来源:Java技术指北 作者:Java技术指北 2023-10-11 15:42 次阅读

引子

首先,小编声明一下,这里讲的Exception不仅仅是Exception一个类,而是异常机制,就像下面图中的所有(含继承Error和Exception的)。

图片
异常类图

当然JDK中更为细致的异常继承体系也不是本篇探讨内容,本次呢,指北君将对异常在JVM层面的执行原理和ARM进行介绍,这里ARM也不是芯片架构,而是指自动资源管理。

异常表

要想了解异常执行原理,异常表是一个最佳的入口,异常表是什么?我来看看下面的数据结构描述:

exception_table {
    u2 start_pc;
    u2 end_pc;
    u2 handler_pc;
    u2 catch_type;
}

它是虚拟机中用于表述异常处理的一种数据结构,我再来看异常表的样例,下面是一段包含try-catch代码编译后的字节码中的内容:

from    to  target type
            8    41    41   Class java/lang/IllegalArgumentException
            8    41    41   Class java/io/IOException
            8    53    63   any

逻辑上的表述可以用下图表示:

图片

异常类图

  1. 监测从8-41(41不包含)号指令的IllegalArgumentException
  2. 监测从8-41指令的IOException
  3. 监测从8到53指令的结束动作,包含三种情况:跳出指令(比如return指令集);athrow指令且没有匹配的异常类型;指令执行到最后一条
  4. 如果监测到指定动作,则按照异常表进行跳转

现在,回到异常表,我们可以看到异常表包含多条异常处理数据,每条数据包含四个属性

  • from 监控的指令集起始编号
  • to 监控的指令集结束编号
  • target 满足条件后指令跳转目标
  • 异常匹配的类型,特殊类型any,对应fanally块,监控try块和catch块

对于return,athrow等指令,执行顺序需要注意,指令是在对应的处理之后执行。

可能会让你意识混乱的例子:

public String execOrder(int sn) {
        StringBuilder build = new StringBuilder();
        try {
            build.append("try-block");
            if(sn == 0) {
                return build.append(", end").toString();
            }
        }catch(RuntimeException e) {
            build.append(", catch-block");
        }finally{
            build.append(", finally-block");
        }
        
        return build.toString();
    }

我们之前说过finally块会在return之前执行,那是不是执行结果是:try->finally->end这种顺序呢?实际的执行的结果是:try-block,end。可以看到,finally块没有对结果形成影响,当然,这并不说它没执行,只是reutrn的结果在执行finally块时已经计算出结果了,在执行完finally块后将之前计算的结果返回了而已。所以我们要深入理解了执行的原理,才能正确理解结果。

ARM 自动资源管理

讲完前面的异常执行原理后,指北君现在给大家介绍异常机制在JDK1.7中一个优化特性:自动资源管理。经常使用IO的小伙伴一定对关闭IO很烦,写法繁琐,关闭前还要做判断,并且在关闭块代码还要加try-catch,就如同下面类似的代码:

InputStreamReader in = null;
        OutputStreamWriter out = null;
        try {
            in = new InputStreamReader(new FileInputStream(""));
        }catch(IOException e) {
            
        }finally {
            try {
                if(in != null) {
                    in.close();
                }
                if(out != null) {
                    in.close();
                }
            }catch(IOException e) {
                
            }
        }

反正指北君每次写这种代码的时候很烦,就是那种啥事没干,占我一块黄金代码位置的感觉,对于有精简代码癖好的人来说,就像吃了一口苍蝇般难受。有了ARM后,我们再来看看新的写法:

public void sample2() {
        try (InputStreamReader in  = new InputStreamReader(new FileInputStream(""))){
            in.read();
        }catch(IOException e) {
            
        }finally {
            
        }
    }

是不是简洁多了,资源直接在try后的括号内进行声明,而且不需要显式的关闭流的代码,这难道就是ARM!是不是有点小兴奋!对于ARM自动资源管理要点如下:

  • 在try后的括号内声明需要自动关闭的资源
  • 资源必须实现一个关键接口:AutoCloseable。在满足上面的条件后,JDK将为我们自动关闭资源。当然这种写法即使想手动关闭,在catch和finally部分也拿不到资源引用。

又到了追根溯源环节了,自动资源管理是如何实现的呢?先看看class文件有啥变化。

21: aload_3
22: invokevirtual #112                // Method java/io/InputStreamReader.read:()I
25: pop
26: ldc           #51                 // String try-block
28: astore        4
30: aload_3
31: ifnull        94
34: aload_3
35: invokevirtual #103                // Method java/io/InputStreamReader.close:()V
38: goto          94
41: astore_1
42: aload_3
43: ifnull        50
46: aload_3
47: invokevirtual #103                // Method java/io/InputStreamReader.close:()V
50: aload_1
51: athrow
52: astore_2

对比之前的字节码文件,我们明显发现虽然代码行数少了,但是Class编译后的内容一点都没少,而且异常表中除了finally对应的处理,还增加了额外的部分。具体几个不同点:

  1. 字节码中竟然有close调用
  2. 异常表中增加了内容
Exception table:
    from    to  target type
       21    30    41   any
        4    52    52   any
        0    74    74   Class java/io/IOException
        0    78    85   any

好奇怪的异常表,我们查看指令,可以明显找出最后一条是对应finally处理。前面的呢?经过分析我们发现前面是finally形式的关闭资源。看到这里,结果就很明显了,自动资源管理实际是上编译帮助我们做了显示关闭的逻辑,在JVM执行层面没有增加新的功能。简而言之,自动资源管理是编译器层面的改进,通过扩展语法和增强编译能力(增加自动的资源关闭能力)来实现自动化编码。

总结

关于Java的异常的原理,以及自动资源管理的用法和实现方式,就给大家介绍到这里。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 芯片
    +关注

    关注

    447

    文章

    47804

    浏览量

    409172
  • JAVA
    +关注

    关注

    19

    文章

    2904

    浏览量

    102996
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66784
  • 编译
    +关注

    关注

    0

    文章

    615

    浏览量

    32397
  • JVM
    JVM
    +关注

    关注

    0

    文章

    152

    浏览量

    12129
收藏 人收藏

    评论

    相关推荐

    InfiniiVision DSO6104L上的远程Web访问java异常错误

    Oscope。当我最初尝试启动远程面板命令时,我得到一个java异常错误。我将浏览器安全性设置为最低级别并启用了java脚本,并使用范围ip地址授予了网页访问权限。我在Explorer,Chrome
    发表于 10-11 11:44

    请问Java异常错误该怎么办?

    在成功构建之后,我继续进行Flash,但得到Java异常错误(见下文)。Matlab版本R2014BMICROMPLATS 3.37 MPLAB X IDE V3.26XC16
    发表于 10-14 11:19

    MPLABX IDE 3.40和3.45 Win 7编辑器Java异常该怎么办?

    刚刚安装了MPLAB X IDE 3.40,并有文本编辑器的问题。如果我尝试打开任何源文件,我会得到下面的Java异常java. Lang.CassCasExtExc
    发表于 10-28 09:45

    如何处理MHC V1.0.7.9java异常

    ]***生成配置***[Info][Info]生成项目ba生成文件。[Error]Generate由于未处理的异常而失败。[Error]Exception堆栈跟踪:[Error
    发表于 05-13 11:02

    Java异常体系级处理办法

      一、异常简介  优秀的程序代码,都在追求高效,安全,和低错误率,但是程序中的异常是无法避免的,降低异常出现的频率是关键,异常出现如何处理是另一个重要方面,
    发表于 01-05 17:48

    Java异常处理及其应用

    Java异常处理引出 假设您要编写一个 Java 程序,该程序读入用户输入的一行文本,并在终端显示该文本。 程序如下: 1 import java.io.*;2 public c
    发表于 11-09 12:03 15次下载

    Java异常处理PPT课件

    Java 异常处理: 什么情况下使用例外机制? n当方法因为自身无法控制的原因而不能完成其任务 n文件不存在,网络连接无法建立 n处理在方法、类库、类中抛出的例外 n如FileInputStream.re
    发表于 08-19 17:12 44次下载
    <b class='flag-5'>Java</b><b class='flag-5'>异常</b>处理PPT课件

    Java异常处理之try,catch,finally,throw,throws

    后,程序继续运行。 java异常处理是通过5个关键字来实现的:try、catch、finally、throw、throws。 二:java异常类的层次结构 三。常见的
    发表于 09-27 11:17 0次下载
    <b class='flag-5'>Java</b><b class='flag-5'>异常</b>处理之try,catch,finally,throw,throws

    java异常处理的设计与重构

    寻找出错的根源?但是如果一个项目异常处理设计地过多,又会严重影响到代码质量以及程序的性能。因此,如何高效简洁地设计异常处理是一门艺术,本文下面先讲述Java异常机制最基础的知识,然后给
    发表于 09-27 15:40 1次下载
    <b class='flag-5'>java</b><b class='flag-5'>异常</b>处理的设计与重构

    java异常处理设计和一些建议

    出错从哪里寻找出错的根源?但是如果一个项目异常处理设计地过多,又会严重影响到代码质量以及程序的性能。因此,如何高效简洁地设计异常处理是一门艺术,本文下面先讲述Java异常机制最基础的知
    发表于 09-28 11:48 0次下载
    <b class='flag-5'>java</b><b class='flag-5'>异常</b>处理设计和一些建议

    Java异常选择和使用的误区和经验总结

    本文着重介绍了 Java 异常选择和使用中的一些误区,希望各位读者能够熟练掌握异常处理的一些注意点和原则,注意总结和归纳。只有处理好了异常,才能提升开发人员的基本素养,提高系统的健壮性
    发表于 11-27 08:54 1252次阅读
    <b class='flag-5'>Java</b><b class='flag-5'>异常</b>选择和使用的误区和经验总结

    对处理 Java 异常三原则的详细分析

    Java异常提供了一种识别及响应错误情况的一致性机制,有效地异常处理能使程序更加健壮、易于调试。
    的头像 发表于 12-25 11:09 3507次阅读
    对处理 <b class='flag-5'>Java</b> <b class='flag-5'>异常</b>三原则的详细分析

    java教程之如何进行Java异常处理?

    本文档的主要内容详细介绍的是java教程之如何进行Java异常处理?
    发表于 09-28 17:16 0次下载

    Java教程之零点起飞学Java异常处理资料说明

    Java语言提供了异常机制来处理程序运行过程中可能发生的各种非正常事件。通过异常处理机制,大大提高了程序的健壮性。Java语言对各种异常进行
    发表于 02-20 10:41 11次下载
    <b class='flag-5'>Java</b>教程之零点起飞学<b class='flag-5'>Java</b>的<b class='flag-5'>异常</b>处理资料说明

    Java异常的习题和代码分析

    Java异常的习题和代码分析
    发表于 07-08 14:54 5次下载
    <b class='flag-5'>Java</b><b class='flag-5'>异常</b>的习题和代码分析