读《深入理解Java虚拟机》有感——第一部分:Class文件的结构
读《深入理解Java虚拟机》有感——第一部分:Class文件的结构
读《深入理解Java虚拟机》有感——第一部分:Class文件的结构
1.产生
源码(.java文件)——>编译器(如:javac)——>字节码(.class文件)——>虚拟机(如:HotSpot)执行
2.Class文件
1)构成:
2)例子:
[1] .java文件
桌面/test/test/Father.java、桌面/test/test/Father_interface.java、桌面/test/Son.java ;
[2]编译出.class文件
cd 桌面/test;
桌面/test>javac Son.java;
[3]查看.class文件
桌面/test>javap -verbose Son;
Classfile /C:/Users/Administrator/Desktop/test/Son.class
Last modified 2016-4-11; size 1005 bytes
MD5 checksum 7d138d76267a6bb372eba05296e2c932魔数
Compiled from "Son.java"
public class test.Son extends test.Father implements test.Father_interface索引(1类索引、2父类索引、3接口索引,指向常量池)
SourceFile: "Son.java"
minor version: 0
major version: 51主板本号
flags: ACC_PUBLIC, ACC_SUPER访问标志<当前类>
Constant pool:常量池
#1 = Methodref #16.#33 // test/Father."<init>":()V 符号引用{
#2 = Fieldref #15.#34 // test/Son.sId_literal:I
#3 = Fieldref #35.#36 // java/lang/System.out:Ljava/io/PrintStream;
#4 = Class #37 // java/lang/StringBuilder
#5 = Methodref #4.#33 // java/lang/StringBuilder."<init>":()V
#6 = String #38 // statical_sId =
#7 = Methodref #4.#39 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/Strin
gBuilder;
#8 = Fieldref #15.#40 // test/Son.statical_sId:I
#9 = Methodref #4.#41 // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
#10 = Methodref #4.#42 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#11 = Methodref #43.#44 // java/io/PrintStream.println:(Ljava/lang/String;)V
#12 = String #45 // Son实例构造器!
#13 = String #46 // hello!this is son!
#14 = String #47 // Son类构造器<clinit>执行!
#15 = Class #48 // test/Son 1
#16 = Class #49 // test/Father 2
#17 = Class #50 // test/Father_interface 3 }符号引用
#18 = Utf8 final_sId
#19 = Utf8 I
#20 = Utf8 ConstantValue
#21 = Integer 123 字面量
#22 = Utf8 statical_sId
#23 = Utf8 sId_literal
#24 = Utf8 sId_nonLiteral
#25 = Utf8 <init>
#26 = Utf8 ()V
#27 = Utf8 Code
#28 = Utf8 LineNumberTable
#29 = Utf8 sayHello
#30 = Utf8 <clinit>
#31 = Utf8 SourceFile
#32 = Utf8 Son.java 符号引用{
#33 = NameAndType #25:#26 // "<init>":()V
#34 = NameAndType #23:#19 // sId_literal:I
#35 = Class #51 // java/lang/System
#36 = NameAndType #52:#53 // out:Ljava/io/PrintStream;
#37 = Utf8 java/lang/StringBuilder
#38 = Utf8 statical_sId =
#39 = NameAndType #54:#55 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#40 = NameAndType #22:#19 // statical_sId:I
#41 = NameAndType #54:#56 // append:(I)Ljava/lang/StringBuilder;
#42 = NameAndType #57:#58 // toString:()Ljava/lang/String;
#43 = Class #59 // java/io/PrintStream
#44 = NameAndType #60:#61 // println:(Ljava/lang/String;)V
#45 = Utf8 Son实例构造器! }符号引用
#46 = Utf8 hello!this is son!
#47 = Utf8 Son类构造器<clinit>执行!
#48 = Utf8 test/Son
#49 = Utf8 test/Father
#50 = Utf8 test/Father_interface
#51 = Utf8 java/lang/System
#52 = Utf8 out
#53 = Utf8 Ljava/io/PrintStream;
#54 = Utf8 append
#55 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#56 = Utf8 (I)Ljava/lang/StringBuilder;
#57 = Utf8 toString
#58 = Utf8 ()Ljava/lang/String;
#59 = Utf8 java/io/PrintStream
#60 = Utf8 println
#61 = Utf8 (Ljava/lang/String;)V
{
public test.Son();方法表——实例构造器
flags: ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method test/Father."<init>":()V
4: aload_0
5: bipush 123
7: putfield #2 // Field sId_literal:I
10: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
13: new #4 // class java/lang/StringBuilder
16: dup
17: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
20: ldc #6 // String statical_sId =
22: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/
lang/StringBuilder;
25: getstatic #8 // Field statical_sId:I
28: invokevirtual #9 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilde
r;
31: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
34: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
37: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
40: ldc #12 // String Son实例构造器!
42: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
45: sipush 333
48: putstatic #8 // Field statical_sId:I
51: return
LineNumberTable:
line 15: 0
line 7: 4
line 16: 10
line 17: 37
line 18: 45
line 19: 51
public void sayHello();方法表——sayHello()
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #13 // String hello!this is son!
5: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 21: 0
line 22: 8
static {};方法表——类构造器(或静态代码块)
flags: ACC_STATIC
Code:
stack=3, locals=0, args_size=0
0: bipush 123
2: putstatic #8 // Field statical_sId:I
5: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
8: new #4 // class java/lang/StringBuilder
11: dup
12: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
15: ldc #6 // String statical_sId =
17: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/
lang/StringBuilder;
20: getstatic #8 // Field statical_sId:I
23: invokevirtual #9 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilde
r;
26: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
29: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
32: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
35: ldc #14 // String Son类构造器<clinit>执行!
37: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
40: return
LineNumberTable:
line 6: 0
line 11: 5
line 12: 32
line 13: 40
}
3.总结
魔数、版本号、常量池、访问标志、索引、字段表集合、方法表集合
魔数 | 版本号 | 常量池 | 访问标志 | 索引 | 字段表集合 | 方法表集合 |
后缀名是可以改的, 所以用它来确定真 的是.class文件 |
44=JDK1.0 45=jdk1.1 .... |
字面量:int、double等基本类型数据值 符号引用:(最终指向UTF-8字符串) 1)记录类 访问标志+全限定名 2)记录方法 简单名称+返回类型+参数列表 3)记录成员属性 简单名称+返回类型
|
分为:本类、继承父类类、实现接口 指向“常量池—记录类” |
每张表: 访问标志、(名称、描述【如:返回类型、参数等】)、附加属性attributes(Code属性表、Linumber属性表、局部变量表、异常表等) /** 括号中表示是指向“常量池”*/
|
深入理解Java虚拟机:JVM高级特性与最佳实践 第2版 高清PDF+源码
本文永久更新链接地址:
评论暂时关闭