第二章 JVM 编译

第一章 JVM 概述
第二章 JVM 编译
第三章 JVM 类结构
第四章 JVM 类加载机制

JVM 编译

  • 1. javac 编译 和 javap 查看 class 文件
  • 2. 指令格式
  • 3. 如何学习和理解编译后字节码
    • 3.1 对象创建的例子
      • 3.1.1 Java 代码
      • 3.1.2 编译后的使用 javap 查看的字节码
      • 3.1.3 指令的执行
        • 3.1.3.1 第一条指令 new
        • 3.1.3.2 第二条指令 dup
        • 3.1.3.3 第三条指令 invokespecial
        • 3.1.3.4 第四条指令 astore_1
        • 3.1.3.5 第五条指令 aload_1
  • 4. 关键知识点
  • 5. 代表性的 Java 代码,覆盖了常用的语法
  • 6. 编译后的字节码文件

1. javac 编译 和 javap 查看 class 文件

本章描述的编译是指使用 JDK 自带的 java 工具把源代码编译成 class 文件,重点关注如何把 java 语言编译成 jvm 指令。
第二章 JVM 编译_第1张图片

用户可以使用 javap 工具把二进制的 class 文件转换成用户可以看懂的 jvm 指令文本,来方便我们理解编译后的 class 文件,-p 参数会展示私有的方法的属性,-v 参数会展示尽可能多的信息。示例:javap -v -p HelloWorld。如果你使用了编译器 idea,可以使用 jclasslib 插件来查看 class 文件信息。

2. 指令格式

指令的格式: [ [ ... ]] []
index 是指从方法开始的位置到当前指令的偏移量
opcode 是指操作码
operand 是指操作数,操作码的参数
comment 由编译器或者用户生成的注释

以下代码对常用的 Java 语法做了示例,可以通过方法名去找对应的字节码实现。字节码实现基本可以和方法一一对应。

3. 如何学习和理解编译后字节码

3.1 对象创建的例子

3.1.1 Java 代码

// 新建类实例、操作数栈相关指令
JavaCompiler compiler = new JavaCompiler();

3.1.2 编译后的使用 javap 查看的字节码

0: new           #2             // class org/compiler/JavaCompiler
3: dup
4: invokespecial #3             // Method "":()V
7: astore_1
8: aload_1

3.1.3 指令的执行

3.1.3.1 第一条指令 new

参照指令格式 0: new #2 // class org/compiler/JavaCompiler,0 代表当前指令在方法中的偏移量是0,代表第一条指令,new是操作符也就是是指令名称,表示当前指令用来创建对象实例,#2是指令的操作数即参数,# 代表内容需要从字节码的常量池 Constant poll中获取,常量池中 #2 对应的内容为 #76 对应的内容 org/compiler/JavaCompiler代表类的全限定名,也就是要创建对象的类型。最后一列的 comment 也帮我们标明了实际的值。执行完这条指令,JVM 就会创建一个 JavaCompiler实例,并把它放入操作数栈中。

Constant pool:
    #1 = Methodref          #24.#75       // java/lang/Object."":()V
    #2 = Class              #76           // org/compiler/JavaCompiler
    #76 = Utf8               org/compiler/JavaCompiler
3.1.3.2 第二条指令 dup

执行完第二条指令 dup,在操作数栈中拷贝栈顶元素并推入栈内,此时本内有两个 this。

3.1.3.3 第三条指令 invokespecial

执行第三条指令 invokespecial #3会调用对象的 init方法并做初始化,需要从栈内弹出一个 this 参数,但是此方法无返回值,此时栈内还剩一个 this。

3.1.3.4 第四条指令 astore_1

执行第四条指令 astore_1把弹出一个操作数栈元素,并保存在本地变量 1 中。

3.1.3.5 第五条指令 aload_1

执行第五条指令 aload_1又把本地变量 1 的值推入操作数栈中供后面的方法使用。

第二章 JVM 编译_第2张图片

4. 关键知识点

基础的指令知识请参考Compiling for the Java Virtual Machine

  1. 新建类实例的指令比构造方法中的指令多了一个 dup指令,dup 是操作数栈的指令,它不需要关心数据的类型,作用是拷贝一份和当前栈顶元素一模一样的数据并推入栈内,作用是在对象初始化的时候为初始化后的 aload_n 提供 this 操作数,栈中 this 被 invokeSpecial init() 拿去执行,初始化方法没有返回值,如果不 dup 一个栈中就没有 this 了。
  2. 方法调用和静态方法调用的参数不一样,方法调用需要带上 this 作为第一个参数,参数个数和本地变量的个数都比静态方法多一个
  3. 同步关键字加在方法上,JVM 会在执行方法的 invoke 和 return 指令的时候判断方法上是否有标志 ACC_SYNCHRONIZED 并做相应的处理,确保方法不管是正常还是异常退出都能保证线程安全;同步代码块通过 moniterenter 和 monitorexist 指令实现,同时方法中会生成异常表,当方法中任务异常发生时都会执行成对的 monitorexit 指令来保证当前线程能从监视器中正常退出。
  4. switch 指令有两种实现方式,JVM 会对 switch 值稀疏的采用 lookuptable 实现方式(本例中使用此方式),对 switch 值紧凑的采用 tableswitch 实现方式。tableswitch 方式更高效,但是如果值稀疏字节码文件会很大。可以参考 Difference between JVM’s LookupSwitch and TableSwitch?。

5. 代表性的 Java 代码,覆盖了常用的语法

public class JavaCompiler {

    private static final Integer LIMIT_100 = 100;
    private static final String FINALLY = "finally";

    public static void main(String[] args) {
        try {
            // 访问运行时常量池
            // 新建类实例、操作数栈相关指令
            JavaCompiler compiler = new JavaCompiler();
            // 调用方法、接收参数
            compiler.setCount(0);
            // 同步代码块
            int size = compiler.synchronizedBlockAddTwoInteger(compiler.addToLimit(), LIMIT_100);
            // 数组
            int[] array = new int[size];
            final int mod = size / LIMIT_100;
            int switchResult;
            // switch
            switch (mod) {
                case 0: switchResult = 0; break;
                case 1: switchResult = 1; break;
                case 2: switchResult = 2; break;
                case 5: switchResult = 5; break;
                case 10: switchResult = 10; break;
                case 20: switchResult = 20; break;
                case 30: switchResult = 30; break;
                default: switchResult = 99;
            }
            // 调用静态方法, 接收参数,同步方法
            System.out.println("result:" + compiler.synchronizedAddTwoInteger(JavaCompiler.staticAddTwoInteger(switchResult,mod),LIMIT_100));
        } catch (Exception e) {
            // 异常处理指令
            System.out.println(e.getMessage());
        } finally {
            // finally 指令
            System.out.println(FINALLY);
        }
    }


    int addToLimit () {
        // 常量 0, 100 控制结构
        for (int i = 0; i < LIMIT_100; i++) {
            // 计算指令
            count += i;
        }
        return count;
    }

    /**
     * 调用实例方法, 接收参数
     */
    int synchronizedBlockAddTwoInteger (Integer intA, Integer intB) {
        synchronized (this) {
            return intA + intB;
        }
    }

    /**
     * 同步调用实例方法, 接收参数
     */
    synchronized int synchronizedAddTwoInteger (Integer intA, Integer intB) {
        return intA + intB;
    }

    /**
     * 调用静态方法, 接收参数
     */
    public static int staticAddTwoInteger (Integer intA, Integer intB) {
        return intA + intB;
    }

    /**
     * 本地变量
     */
    private Integer count;

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }
} 

6. 编译后的字节码文件

javap -v -p JavaCompiler

$ javap -v -p JavaCompiler
Warning: Binary file JavaCompiler contains org.compiler.JavaCompiler
Classfile /Users/geguirong/Downloads/project/mchz/no_maven/out/production/no_maven/org/compiler/JavaCompiler.class
  Last modified Mar 23, 2022; size 2667 bytes
  MD5 checksum 1f9d9cc17562aaf4093ff03008077c51
  Compiled from "JavaCompiler.java"
public class org.compiler.JavaCompiler
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
    #1 = Methodref          #24.#75       // java/lang/Object."":()V
    #2 = Class              #76           // org/compiler/JavaCompiler
    #3 = Methodref          #2.#75        // org/compiler/JavaCompiler."":()V
    #4 = Methodref          #77.#78       // java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    #5 = Methodref          #2.#79        // org/compiler/JavaCompiler.setCount:(Ljava/lang/Integer;)V
    #6 = Methodref          #2.#80        // org/compiler/JavaCompiler.addToLimit:()I
    #7 = Fieldref           #2.#81        // org/compiler/JavaCompiler.LIMIT_100:Ljava/lang/Integer;
    #8 = Methodref          #2.#82        // org/compiler/JavaCompiler.synchronizedBlockAddTwoInteger:(Ljava/lang/Integer;Ljava/lang/Integer;)I
    #9 = Methodref          #77.#83       // java/lang/Integer.intValue:()I
   #10 = Fieldref           #84.#85       // java/lang/System.out:Ljava/io/PrintStream;
   #11 = Class              #86           // java/lang/StringBuilder
   #12 = Methodref          #11.#75       // java/lang/StringBuilder."":()V
   #13 = String             #87           // result:
   #14 = Methodref          #11.#88       // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #15 = Methodref          #2.#89        // org/compiler/JavaCompiler.staticAddTwoInteger:(Ljava/lang/Integer;Ljava/lang/Integer;)I
   #16 = Methodref          #2.#90        // org/compiler/JavaCompiler.synchronizedAddTwoInteger:(Ljava/lang/Integer;Ljava/lang/Integer;)I
   #17 = Methodref          #11.#91       // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   #18 = Methodref          #11.#92       // java/lang/StringBuilder.toString:()Ljava/lang/String;
   #19 = Methodref          #93.#94       // java/io/PrintStream.println:(Ljava/lang/String;)V
   #20 = String             #95           // finally
   #21 = Class              #96           // java/lang/Exception
   #22 = Methodref          #21.#97       // java/lang/Exception.getMessage:()Ljava/lang/String;
   #23 = Fieldref           #2.#98        // org/compiler/JavaCompiler.count:Ljava/lang/Integer;
   #24 = Class              #99           // java/lang/Object
   #25 = Utf8               LIMIT_100
   #26 = Utf8               Ljava/lang/Integer;
   #27 = Utf8               FINALLY
   #28 = Utf8               Ljava/lang/String;
   #29 = Utf8               ConstantValue
   #30 = Utf8               count
   #31 = Utf8               
   #32 = Utf8               ()V
   #33 = Utf8               Code
   #34 = Utf8               LineNumberTable
   #35 = Utf8               LocalVariableTable
   #36 = Utf8               this
   #37 = Utf8               Lorg/compiler/JavaCompiler;
   #38 = Utf8               main
   #39 = Utf8               ([Ljava/lang/String;)V
   #40 = Utf8               switchResult
   #41 = Utf8               I
   #42 = Utf8               compiler
   #43 = Utf8               size
   #44 = Utf8               array
   #45 = Utf8               [I
   #46 = Utf8               mod
   #47 = Utf8               e
   #48 = Utf8               Ljava/lang/Exception;
   #49 = Utf8               args
   #50 = Utf8               [Ljava/lang/String;
   #51 = Utf8               StackMapTable
   #52 = Class              #50           // "[Ljava/lang/String;"
   #53 = Class              #76           // org/compiler/JavaCompiler
   #54 = Class              #45           // "[I"
   #55 = Class              #96           // java/lang/Exception
   #56 = Class              #100          // java/lang/Throwable
   #57 = Utf8               addToLimit
   #58 = Utf8               ()I
   #59 = Utf8               i
   #60 = Utf8               synchronizedBlockAddTwoInteger
   #61 = Utf8               (Ljava/lang/Integer;Ljava/lang/Integer;)I
   #62 = Utf8               intA
   #63 = Utf8               intB
   #64 = Class              #101          // java/lang/Integer
   #65 = Class              #99           // java/lang/Object
   #66 = Utf8               synchronizedAddTwoInteger
   #67 = Utf8               staticAddTwoInteger
   #68 = Utf8               getCount
   #69 = Utf8               ()Ljava/lang/Integer;
   #70 = Utf8               setCount
   #71 = Utf8               (Ljava/lang/Integer;)V
   #72 = Utf8               
   #73 = Utf8               SourceFile
   #74 = Utf8               JavaCompiler.java
   #75 = NameAndType        #31:#32       // "":()V
   #76 = Utf8               org/compiler/JavaCompiler
   #77 = Class              #101          // java/lang/Integer
   #78 = NameAndType        #102:#103     // valueOf:(I)Ljava/lang/Integer;
   #79 = NameAndType        #70:#71       // setCount:(Ljava/lang/Integer;)V
   #80 = NameAndType        #57:#58       // addToLimit:()I
   #81 = NameAndType        #25:#26       // LIMIT_100:Ljava/lang/Integer;
   #82 = NameAndType        #60:#61       // synchronizedBlockAddTwoInteger:(Ljava/lang/Integer;Ljava/lang/Integer;)I
   #83 = NameAndType        #104:#58      // intValue:()I
   #84 = Class              #105          // java/lang/System
   #85 = NameAndType        #106:#107     // out:Ljava/io/PrintStream;
   #86 = Utf8               java/lang/StringBuilder
   #87 = Utf8               result:
   #88 = NameAndType        #108:#109     // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #89 = NameAndType        #67:#61       // staticAddTwoInteger:(Ljava/lang/Integer;Ljava/lang/Integer;)I
   #90 = NameAndType        #66:#61       // synchronizedAddTwoInteger:(Ljava/lang/Integer;Ljava/lang/Integer;)I
   #91 = NameAndType        #108:#110     // append:(I)Ljava/lang/StringBuilder;
   #92 = NameAndType        #111:#112     // toString:()Ljava/lang/String;
   #93 = Class              #113          // java/io/PrintStream
   #94 = NameAndType        #114:#115     // println:(Ljava/lang/String;)V
   #95 = Utf8               finally
   #96 = Utf8               java/lang/Exception
   #97 = NameAndType        #116:#112     // getMessage:()Ljava/lang/String;
   #98 = NameAndType        #30:#26       // count:Ljava/lang/Integer;
   #99 = Utf8               java/lang/Object
  #100 = Utf8               java/lang/Throwable
  #101 = Utf8               java/lang/Integer
  #102 = Utf8               valueOf
  #103 = Utf8               (I)Ljava/lang/Integer;
  #104 = Utf8               intValue
  #105 = Utf8               java/lang/System
  #106 = Utf8               out
  #107 = Utf8               Ljava/io/PrintStream;
  #108 = Utf8               append
  #109 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #110 = Utf8               (I)Ljava/lang/StringBuilder;
  #111 = Utf8               toString
  #112 = Utf8               ()Ljava/lang/String;
  #113 = Utf8               java/io/PrintStream
  #114 = Utf8               println
  #115 = Utf8               (Ljava/lang/String;)V
  #116 = Utf8               getMessage
{
  private static final java.lang.Integer LIMIT_100;
    descriptor: Ljava/lang/Integer;
    flags: ACC_PRIVATE, ACC_STATIC, ACC_FINAL

  private static final java.lang.String FINALLY;
    descriptor: Ljava/lang/String;
    flags: ACC_PRIVATE, ACC_STATIC, ACC_FINAL
    ConstantValue: String finally

  private java.lang.Integer count;
    descriptor: Ljava/lang/Integer;
    flags: ACC_PRIVATE

  public org.compiler.JavaCompiler();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."":()V
         4: return
      LineNumberTable:
        line 7: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lorg/compiler/JavaCompiler;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=5, locals=7, args_size=1
         0: new           #2                  // class org/compiler/JavaCompiler
         3: dup
         4: invokespecial #3                  // Method "":()V
         7: astore_1
         8: aload_1
         9: iconst_0
        10: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        13: invokevirtual #5                  // Method setCount:(Ljava/lang/Integer;)V
        16: aload_1
        17: aload_1
        18: invokevirtual #6                  // Method addToLimit:()I
        21: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        24: getstatic     #7                  // Field LIMIT_100:Ljava/lang/Integer;
        27: invokevirtual #8                  // Method synchronizedBlockAddTwoInteger:(Ljava/lang/Integer;Ljava/lang/Integer;)I
        30: istore_2
        31: iload_2
        32: newarray       int
        34: astore_3
        35: iload_2
        36: getstatic     #7                  // Field LIMIT_100:Ljava/lang/Integer;
        39: invokevirtual #9                  // Method java/lang/Integer.intValue:()I
        42: idiv
        43: istore        4
        45: iload         4
        47: lookupswitch  { // 7
                       0: 112
                       1: 118
                       2: 124
                       5: 130
                      10: 136
                      20: 143
                      30: 150
                 default: 157
            }
       112: iconst_0
       113: istore        5
       115: goto          161
       118: iconst_1
       119: istore        5
       121: goto          161
       124: iconst_2
       125: istore        5
       127: goto          161
       130: iconst_5
       131: istore        5
       133: goto          161
       136: bipush        10
       138: istore        5
       140: goto          161
       143: bipush        20
       145: istore        5
       147: goto          161
       150: bipush        30
       152: istore        5
       154: goto          161
       157: bipush        99
       159: istore        5
       161: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
       164: new           #11                 // class java/lang/StringBuilder
       167: dup
       168: invokespecial #12                 // Method java/lang/StringBuilder."":()V
       171: ldc           #13                 // String result:
       173: invokevirtual #14                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       176: aload_1
       177: iload         5
       179: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       182: iload         4
       184: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       187: invokestatic  #15                 // Method staticAddTwoInteger:(Ljava/lang/Integer;Ljava/lang/Integer;)I
       190: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       193: getstatic     #7                  // Field LIMIT_100:Ljava/lang/Integer;
       196: invokevirtual #16                 // Method synchronizedAddTwoInteger:(Ljava/lang/Integer;Ljava/lang/Integer;)I
       199: invokevirtual #17                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
       202: invokevirtual #18                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       205: invokevirtual #19                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       208: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
       211: ldc           #20                 // String finally
       213: invokevirtual #19                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       216: goto          254
       219: astore_1
       220: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
       223: aload_1
       224: invokevirtual #22                 // Method java/lang/Exception.getMessage:()Ljava/lang/String;
       227: invokevirtual #19                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       230: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
       233: ldc           #20                 // String finally
       235: invokevirtual #19                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       238: goto          254
       241: astore        6
       243: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
       246: ldc           #20                 // String finally
       248: invokevirtual #19                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       251: aload         6
       253: athrow
       254: return
      Exception table:
         from    to  target type
             0   208   219   Class java/lang/Exception
             0   208   241   any
           219   230   241   any
           241   243   241   any
      LineNumberTable:
        line 16: 0
        line 18: 8
        line 20: 16
        line 22: 31
        line 23: 35
        line 26: 45
        line 27: 112
        line 28: 118
        line 29: 124
        line 30: 130
        line 31: 136
        line 32: 143
        line 33: 150
        line 34: 157
        line 37: 161
        line 43: 208
        line 44: 216
        line 38: 219
        line 40: 220
        line 43: 230
        line 44: 238
        line 43: 241
        line 44: 251
        line 45: 254
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
          115       3     5 switchResult   I
          121       3     5 switchResult   I
          127       3     5 switchResult   I
          133       3     5 switchResult   I
          140       3     5 switchResult   I
          147       3     5 switchResult   I
          154       3     5 switchResult   I
            8     200     1 compiler   Lorg/compiler/JavaCompiler;
           31     177     2  size   I
           35     173     3 array   [I
           45     163     4   mod   I
          161      47     5 switchResult   I
          220      10     1     e   Ljava/lang/Exception;
            0     255     0  args   [Ljava/lang/String;
      StackMapTable: number_of_entries = 12
        frame_type = 255 /* full_frame */
          offset_delta = 112
          locals = [ class "[Ljava/lang/String;", class org/compiler/JavaCompiler, int, class "[I", int ]
          stack = []
        frame_type = 5 /* same */
        frame_type = 5 /* same */
        frame_type = 5 /* same */
        frame_type = 5 /* same */
        frame_type = 6 /* same */
        frame_type = 6 /* same */
        frame_type = 6 /* same */
        frame_type = 252 /* append */
          offset_delta = 3
          locals = [ int ]
        frame_type = 255 /* full_frame */
          offset_delta = 57
          locals = [ class "[Ljava/lang/String;" ]
          stack = [ class java/lang/Exception ]
        frame_type = 85 /* same_locals_1_stack_item */
          stack = [ class java/lang/Throwable ]
        frame_type = 12 /* same */

  int addToLimit();
    descriptor: ()I
    flags:
    Code:
      stack=3, locals=2, args_size=1
         0: iconst_0
         1: istore_1
         2: iload_1
         3: getstatic     #7                  // Field LIMIT_100:Ljava/lang/Integer;
         6: invokevirtual #9                  // Method java/lang/Integer.intValue:()I
         9: if_icmpge     34
        12: aload_0
        13: aload_0
        14: getfield      #23                 // Field count:Ljava/lang/Integer;
        17: invokevirtual #9                  // Method java/lang/Integer.intValue:()I
        20: iload_1
        21: iadd
        22: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        25: putfield      #23                 // Field count:Ljava/lang/Integer;
        28: iinc          1, 1
        31: goto          2
        34: aload_0
        35: getfield      #23                 // Field count:Ljava/lang/Integer;
        38: invokevirtual #9                  // Method java/lang/Integer.intValue:()I
        41: ireturn
      LineNumberTable:
        line 50: 0
        line 52: 12
        line 50: 28
        line 54: 34
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            2      32     1     i   I
            0      42     0  this   Lorg/compiler/JavaCompiler;
      StackMapTable: number_of_entries = 2
        frame_type = 252 /* append */
          offset_delta = 2
          locals = [ int ]
        frame_type = 250 /* chop */
          offset_delta = 31

  int synchronizedBlockAddTwoInteger(java.lang.Integer, java.lang.Integer);
    descriptor: (Ljava/lang/Integer;Ljava/lang/Integer;)I
    flags:
    Code:
      stack=2, locals=5, args_size=3
         0: aload_0
         1: dup
         2: astore_3
         3: monitorenter
         4: aload_1
         5: invokevirtual #9                  // Method java/lang/Integer.intValue:()I
         8: aload_2
         9: invokevirtual #9                  // Method java/lang/Integer.intValue:()I
        12: iadd
        13: aload_3
        14: monitorexit
        15: ireturn
        16: astore        4
        18: aload_3
        19: monitorexit
        20: aload         4
        22: athrow
      Exception table:
         from    to  target type
             4    15    16   any
            16    20    16   any
      LineNumberTable:
        line 61: 0
        line 62: 4
        line 63: 16
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      23     0  this   Lorg/compiler/JavaCompiler;
            0      23     1  intA   Ljava/lang/Integer;
            0      23     2  intB   Ljava/lang/Integer;
      StackMapTable: number_of_entries = 1
        frame_type = 255 /* full_frame */
          offset_delta = 16
          locals = [ class org/compiler/JavaCompiler, class java/lang/Integer, class java/lang/Integer, class java/lang/Object ]
          stack = [ class java/lang/Throwable ]

  synchronized int synchronizedAddTwoInteger(java.lang.Integer, java.lang.Integer);
    descriptor: (Ljava/lang/Integer;Ljava/lang/Integer;)I
    flags: ACC_SYNCHRONIZED
    Code:
      stack=2, locals=3, args_size=3
         0: aload_1
         1: invokevirtual #9                  // Method java/lang/Integer.intValue:()I
         4: aload_2
         5: invokevirtual #9                  // Method java/lang/Integer.intValue:()I
         8: iadd
         9: ireturn
      LineNumberTable:
        line 70: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      10     0  this   Lorg/compiler/JavaCompiler;
            0      10     1  intA   Ljava/lang/Integer;
            0      10     2  intB   Ljava/lang/Integer;

  public static int staticAddTwoInteger(java.lang.Integer, java.lang.Integer);
    descriptor: (Ljava/lang/Integer;Ljava/lang/Integer;)I
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: invokevirtual #9                  // Method java/lang/Integer.intValue:()I
         4: aload_1
         5: invokevirtual #9                  // Method java/lang/Integer.intValue:()I
         8: iadd
         9: ireturn
      LineNumberTable:
        line 77: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      10     0  intA   Ljava/lang/Integer;
            0      10     1  intB   Ljava/lang/Integer;

  public java.lang.Integer getCount();
    descriptor: ()Ljava/lang/Integer;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #23                 // Field count:Ljava/lang/Integer;
         4: areturn
      LineNumberTable:
        line 86: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lorg/compiler/JavaCompiler;

  public void setCount(java.lang.Integer);
    descriptor: (Ljava/lang/Integer;)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #23                 // Field count:Ljava/lang/Integer;
         5: return
      LineNumberTable:
        line 90: 0
        line 91: 5
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Lorg/compiler/JavaCompiler;
            0       6     1 count   Ljava/lang/Integer;

  static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: bipush        100
         2: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
         5: putstatic     #7                  // Field LIMIT_100:Ljava/lang/Integer;
         8: return
      LineNumberTable:
        line 9: 0
}
SourceFile: "JavaCompiler.java"

你可能感兴趣的:(#,Jvm,JVM,编译,字节码,指令)