jvm_字节码_概述

Java字节码是java源文件编译只有的产物,供jvm加载执行的十六进制数据。

在字节码文件中,每2个字符作为一个字节。
jvm字节码描述了java编译以后的产物。主要由以下几部分组成: 
1.	魔数,作为class文件的标识
2. 主次版本号
3. 常量池
4. accessFlag 访问标志
5. 类名
6. 父类名
7. 接口数量
8. field数,field表
9. 方法数,方法表
10. attribute数 attribute表
......
以上各数据组合成一个完整的字节码文件,包括了我们在java类中标书的一切信息,
只不过是以字节码形式存在的,主要供机器读取,而不是正常人。

java 创新性的提出字节码的概念,这是java语言可以跨平台的重要存在。

java 和 jvm虚拟机

java语言规范和jvm虚拟机规范是分开的。java语言只不过是jvm规范中一个最重要的分支。
原则上只要是符合规范的字节码文件,jvm都可以执行。jvm并不关心class文件的来源。
以及class文件是由于哪些语言编译的产物。
事实上,jython,jruby groovy 等都是运行在jvm之上的语言。

在以后的文章中会针对一个简单类的字节码进行反编译,来深入进行字节码学习。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
		
public class MyClass {

private static int a = 1;

public int getA() {
return this.a;
}

public void setA(int a) {
this.a = a;
}

}

对以上源文件生成的字节码进行反编译,得到结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
	
Last modified Jul 25, 2019; size 524 bytes
MD5 checksum e846819608e7bc904c06a8545263fac1
Compiled from "MyClass.java"
public class com.example.lib.MyClass
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#21 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#22 // com/example/lib/MyClass.a:I
#3 = Class #23 // com/example/lib/MyClass
#4 = Class #24 // java/lang/Object
#5 = Utf8 a
#6 = Utf8 I
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcom/example/lib/MyClass;
#14 = Utf8 getA
#15 = Utf8 ()I
#16 = Utf8 setA
#17 = Utf8 (I)V
#18 = Utf8 <clinit>
#19 = Utf8 SourceFile
#20 = Utf8 MyClass.java
#21 = NameAndType #7:#8 // "<init>":()V
#22 = NameAndType #5:#6 // a:I
#23 = Utf8 com/example/lib/MyClass
#24 = Utf8 java/lang/Object
{
public com.example.lib.MyClass();
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 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/example/lib/MyClass;

public int getA();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: pop
2: getstatic #2 // Field a:I
5: ireturn
LineNumberTable:
line 8: 0
LocalVariableTable:
Start Length Slot Name Signature
0 6 0 this Lcom/example/lib/MyClass;

public void setA(int);
descriptor: (I)V
flags: ACC_PUBLIC
Code:
stack=1, locals=2, args_size=2
0: aload_0
1: pop
2: iload_1
3: putstatic #2 // Field a:I
6: return
LineNumberTable:
line 12: 0
line 13: 6
LocalVariableTable:
Start Length Slot Name Signature
0 7 0 this Lcom/example/lib/MyClass;
0 7 1 a I

static {};
descriptor: ()V
flags: ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: iconst_1
1: putstatic #2 // Field a:I
4: return
LineNumberTable:
line 5: 0
}
SourceFile: "MyClass.java"


我们用工具打开字节码文件,可以看到以下16进制的数据

在后续章节将会对字节码文件进行一个详细的阐述和分析