欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java字节码角度分析异常处理

程序员文章站 2022-04-06 22:39:18
在前面的文章中,有详细地介绍java字节码相关的知识,有兴趣的可以提前了解一下。1.Java字节码的一段旅行经历——提升硬实力12.Java字节码角度分析a++ ——提升硬实力23.Java字节码角度分析条件判断指令 ——提升硬实力34.Java字节码角度分析循环控制 ——提升硬实力45.Java字节码角度分析判断结果 ——提升硬实力56.Java字节码角度分析构造方法 ——提升硬实力67.Java字节码角度分析方法调用 ——提升硬实力78.Java字节码角度分析多态原理 —...

目录

从字节码角度来分析:异常处理

1.1 异常-catch

1.2 异常-多个catch

1.3 异常-multicatch


从字节码角度来分析:异常处理

1.1 异常-catch

// 从字节码角度来分析:异常处理
public class T13_ByteAnalyseException {
    public static void main(String[] args) {
        int i = 0;
        try {
            i = 10;
        } catch (Exception e) {
            i = 20;
        }
    }
}

注意:为了抓住重点,下面的字节码省略了不重要的部分

上述代码通过:javap -v T13_ByteAnalyseException.class进行反编译,得到如下字节码。

 public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=3, args_size=1
         0: iconst_0
         1: istore_1
         2: bipush        10
         4: istore_1
         5: goto          12
         8: astore_2          // 将异常对象引用存入局部变量表的 slot 2号位置
         9: bipush        20
        11: istore_1
        12: return
      Exception table:   // 异常表,含头不含尾;一旦2~4行代码异常就进入异常判断是否是声明的Exception异常一致,如果一致就进入第8行
         from    to  target type
             2     5     8   Class java/lang/Exception
      LineNumberTable:
        line 15: 0
        line 17: 2
        line 20: 5
        line 18: 8
        line 19: 9
        line 21: 12
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            9       3     2     e   Ljava/lang/Exception;
            0      13     0  args   [Ljava/lang/String;
            2      11     1     i   I
      StackMapTable: ...

上述说明:

  1. 可以看到多出来一个Exception table的结构,[from, to)是前闭后开的检测范围,一旦这个范围内的字节码执行出现异常,则通过type匹配异常类型,如果一致,进入target所指示行号
  2. 8行的字节码指令 astore_2 是将异常对象引用存入局部变量表的 slot 2号位置

1.2 异常-多个catch

先来看下异常-多个catch代码示例:

// 从字节码角度来分析:多个 single-catch 块的情况
public class T14_ByteAnalyseMoreSingle_Catch {
    public static void main(String[] args) {
        int i = 0;
        try {
            i = 10;
        } catch (ArithmeticException e) {
            i = 30;
        } catch (NullPointerException e) {
            i = 40;
        } catch (Exception e) {
            i = 50;
        }
    }
}

上述代码通过:javap -v T14_ByteAnalyseMoreSingle_Catch.class进行反编译,得到如下字节码。

 public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=3, args_size=1
         0: iconst_0
         1: istore_1
         2: bipush        10
         4: istore_1
         5: goto          26
         8: astore_2
         9: bipush        30
        11: istore_1
        12: goto          26
        15: astore_2
        16: bipush        40
        18: istore_1
        19: goto          26
        22: astore_2
        23: bipush        50
        25: istore_1
        26: return
      Exception table:
         from    to  target type
             2     5     8   Class java/lang/ArithmeticException
             2     5    15   Class java/lang/NullPointerException
             2     5    22   Class java/lang/Exception
      LineNumberTable: ...
      LocalVariableTable: // 因为异常最终只会出现一种,这里采用了异常引用变量的槽位复用
        Start  Length  Slot  Name   Signature
            9       3     2     e   Ljava/lang/ArithmeticException;
           16       3     2     e   Ljava/lang/NullPointerException;
           23       3     2     e   Ljava/lang/Exception;
            0      27     0  args   [Ljava/lang/String;
            2      25     1     i   I
      StackMapTable: ...

上述说明:

  1. 因为异常出现时,只能进入 Exception table 中一个分支,所以局部变量表 slot 2 位置被共用。也算是一种优化,为节省栈帧内存的使用

1.3 异常-multicatch

先来看下异常-multi_catch代码示例:

// 从字节码角度来分析:multi-catch 的情况
// jdk1.7 新增multi catch
public class T15_ByteAnalyseMulti_Catch {
    public static void main(String[] args) {
        try {
            Method test = T15_ByteAnalyseMulti_Catch.class.getMethod("test");
            test.invoke(null);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    public static void test() {
        System.out.println("ok");
    }
}

上述代码通过:javap -v T15_ByteAnalyseMulti_Catch.class进行反编译,得到如下字节码。

 public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=2, args_size=1
         0: ldc           #2                  // class com/jvm/t07_bytecode/T15_ByteAnalyseMulti_Catch
         2: ldc           #3                  // String test
         4: iconst_0
         5: anewarray     #4                  // class java/lang/Class
         8: invokevirtual #5                  // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
        11: astore_1
        12: aload_1
        13: aconst_null
        14: iconst_0
        15: anewarray     #6                  // class java/lang/Object
        18: invokevirtual #7                  // Method java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
        21: pop
        22: goto          30
        25: astore_1
        26: aload_1
        27: invokevirtual #11                 // e.printStackTrace:()V
        30: return
      Exception table:
         from    to  target type
             0    22    25   Class java/lang/NoSuchMethodException
             0    22    25   Class java/lang/IllegalAccessException
             0    22    25   Class java/lang/reflect/InvocationTargetException
      LineNumberTable: ...
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           12      10     1  test   Ljava/lang/reflect/Method;
           26       4     1     e   Ljava/lang/ReflectiveOperationException;
            0      31     0  args   [Ljava/lang/String;

上述说明:

  1. 异常-multi_catch  字节码 对比 异常-多个catch字节码,并没有特别的地方,只是异常表Exception table 三个异常的 target都一致。也有 异常-多个catch字节码 异常对象引用在局部变量表中槽位复用。

文章最后,给大家推荐一些受欢迎的技术博客链接

  1. Hadoop相关技术博客链接
  2. Spark 核心技术链接
  3. JAVA相关的深度技术博客链接
  4. 超全干货--Flink思维导图,花了3周左右编写、校对
  5. 深入JAVA 的JVM核心原理解决线上各种故障【附案例】
  6. 请谈谈你对volatile的理解?--最近小李子与面试官的一场“硬核较量”
  7. 聊聊RPC通信,经常被问到的一道面试题。源码+笔记,包懂

本文地址:https://blog.csdn.net/weixin_32265569/article/details/108024235

相关标签: java 字节码