请先阅读:
package org.example.operation;
public class ArithmeticOperation {
public static void main(String[] args) {
int a = 0;
int b = -1;
int c = -2;
int d = 6;
int e = 7;
int f = 12345678;
int g = 987654321;
int h = a + d;
int i = e + f;
int j = g - f;
int k = d * e;
int l = f / e;
}
}
使用如下命令:
javap -c -v ArithmeticOperation.class
得到的字节码文件如下:
Classfile /C:/Data/Code/GitHub/GeekbangJavaTrainingCamp/Week_01/Course_01/bytecode/target/classes/org/example/operation/ArithmeticOperation.class
Last modified Oct 20, 2020; size 731 bytes
MD5 checksum 928a5f565c07247f4e352107af9b745e
Compiled from "ArithmeticOperation.java"
public class org.example.operation.ArithmeticOperation
minor version: 0
major version: 51
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #4 // org/example/operation/ArithmeticOperation
super_class: #5 // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
#1 = Methodref #5.#32 // java/lang/Object."<init>":()V
#2 = Integer 12345678
#3 = Integer 987654321
#4 = Class #33 // org/example/operation/ArithmeticOperation
#5 = Class #34 // java/lang/Object
#6 = Utf8 <init>
#7 = Utf8 ()V
#8 = Utf8 Code
#9 = Utf8 LineNumberTable
#10 = Utf8 LocalVariableTable
#11 = Utf8 this
#12 = Utf8 Lorg/example/operation/ArithmeticOperation;
#13 = Utf8 main
#14 = Utf8 ([Ljava/lang/String;)V
#15 = Utf8 args
#16 = Utf8 [Ljava/lang/String;
#17 = Utf8 a
#18 = Utf8 I
#19 = Utf8 b
#20 = Utf8 c
#21 = Utf8 d
#22 = Utf8 e
#23 = Utf8 f
#24 = Utf8 g
#25 = Utf8 h
#26 = Utf8 i
#27 = Utf8 j
#28 = Utf8 k
#29 = Utf8 l
#30 = Utf8 SourceFile
#31 = Utf8 ArithmeticOperation.java
#32 = NameAndType #6:#7 // "<init>":()V
#33 = Utf8 org/example/operation/ArithmeticOperation
#34 = Utf8 java/lang/Object
{
public org.example.operation.ArithmeticOperation();
descriptor: ()V
flags: (0x0001) 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 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lorg/example/operation/ArithmeticOperation;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=13, args_size=1
0: iconst_0
1: istore_1
2: iconst_m1
3: istore_2
4: bipush -2
6: istore_3
7: bipush 6
9: istore 4
11: bipush 7
13: istore 5
15: ldc #2 // int 12345678
17: istore 6
19: ldc #3 // int 987654321
21: istore 7
23: iload_1
24: iload 4
26: iadd
27: istore 8
29: iload 5
31: iload 6
33: iadd
34: istore 9
36: iload 7
38: iload 6
40: isub
41: istore 10
43: iload 4
45: iload 5
47: imul
48: istore 11
50: iload 6
52: iload 5
54: idiv
55: istore 12
57: return
LineNumberTable:
line 5: 0
line 6: 2
line 7: 4
line 8: 7
line 9: 11
line 10: 15
line 11: 19
line 12: 23
line 13: 29
line 14: 36
line 15: 43
line 16: 50
line 17: 57
LocalVariableTable:
Start Length Slot Name Signature
0 58 0 args [Ljava/lang/String;
2 56 1 a I
4 54 2 b I
7 51 3 c I
11 47 4 d I
15 43 5 e I
19 39 6 f I
23 35 7 g I
29 29 8 h I
36 22 9 i I
43 15 10 j I
50 8 11 k I
57 1 12 l I
}
SourceFile: "ArithmeticOperation.java"
在这个简单的示例中,Class的Constant pool中有此class的两个CONSTANT_Integer,后面的指令会用到这两个Integer。 请参照 4.4. The Constant Pool 查看Constant Pool的详细信息。
Constant pool:
#1 = Methodref #5.#32 // java/lang/Object."<init>":()V
#2 = Integer 12345678
#3 = Integer 987654321
以main方法为例,介绍下一个方法的几个重要组成部分:
Signature: 变量的类型。请参照 Table 4.3-A. Interpretation of field descriptors 查看类型的完整信息。
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=13, args_size=1 0: iconst_0 1: istore_1 … LineNumberTable: line 5: 0 line 6: 2 … LocalVariableTable: Start Length Slot Name Signature 0 58 0 args [Ljava/lang/String; 2 56 1 a I 4 54 2 b I 7 51 3 c I 11 47 4 d I 15 43 5 e I 19 39 6 f I 23 35 7 g I 29 29 8 h I 36 22 9 i I 43 15 10 j I 50 8 11 k I 57 1 12 l I
接下来详细讲解下 main 方法的 Code 指令:
下面介绍两个小知识点,以加深对指令的理解,请参照 Chapter 7. Opcode Mnemonics by Opcode 查看Java 11完整的助记符: