第一章 JVM 概述
第二章 JVM 编译
第三章 JVM 类结构
第四章 JVM 类加载机制
JVM 编译
1. javac 编译 和 javap 查看 class 文件
本章描述的编译是指使用 JDK 自带的 java 工具把源代码编译成 class 文件,重点关注如何把 java 语言编译成 jvm 指令。
用户可以使用 javap 工具把二进制的 class 文件转换成用户可以看懂的 jvm 指令文本,来方便我们理解编译后的 class 文件,-p 参数会展示私有的方法的属性,-v 参数会展示尽可能多的信息。示例:javap -v -p HelloWorld。如果你使用了编译器 idea,可以使用 jclasslib 插件来查看 class 文件信息。
2. 指令格式
指令的格式:<index> <opcode> [ <operand1> [ <operand2>... ]] [<comment>]
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 "<init>":()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."<init>":()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 的值推入操作数栈中供后面的方法使用。

4. 关键知识点
基础的指令知识请参考Compiling for the Java Virtual Machine
- 新建类实例的指令比构造方法中的指令多了一个
dup指令,dup 是操作数栈的指令,它不需要关心数据的类型,作用是拷贝一份和当前栈顶元素一模一样的数据并推入栈内,作用是在对象初始化的时候为初始化后的 aload_n 提供 this 操作数,栈中 this 被 invokeSpecial init() 拿去执行,初始化方法没有返回值,如果不 dup 一个栈中就没有 this 了。 - 方法调用和静态方法调用的参数不一样,方法调用需要带上 this 作为第一个参数,参数个数和本地变量的个数都比静态方法多一个
- 同步关键字加在方法上,JVM 会在执行方法的 invoke 和 return 指令的时候判断方法上是否有标志 ACC_SYNCHRONIZED 并做相应的处理,确保方法不管是正常还是异常退出都能保证线程安全;同步代码块通过 moniterenter 和 monitorexist 指令实现,同时方法中会生成异常表,当方法中任务异常发生时都会执行成对的 monitorexit 指令来保证当前线程能从监视器中正常退出。
- 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."<init>":()V
#2 = Class #76 // org/compiler/JavaCompiler
#3 = Methodref #2.#75 // org/compiler/JavaCompiler."<init>":()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."<init>":()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 <init>
#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 <clinit>
#73 = Utf8 SourceFile
#74 = Utf8 JavaCompiler.java
#75 = NameAndType #31:#32 // "<init>":()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."<init>":()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 "<init>":()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."<init>":()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"