jvm(1)解构字节码文件

CSDN上亦山整理的文章,非常有助于理解,目录如下

《Java虚拟机原理图解》

1、class字节码文件

1.1、class文件基本组织结构

1.2、class文件中的常量池

1.2.2、Class文件中的常量池详解(上)

1.2.3、Class文件中的常量池详解(下)

1.3、class文件中的访问标志、类索引、父类索引、接口索引集合

1.4 class文件中的字段表集合–field字段在class文件中是怎样组织的

1.5、 class文件中的方法表集合–method方法在class文件中是怎样组织的

2、机器指令

3、运行时数据区

精彩片段:

目前的Sun javac编译器的选择是:如果使用finalstatic同时修饰一个final字段,并且这个字段是基本类型或者String类型的,那么编译器在编译这个字段的时候,会在对应的field_info结构体中增加一个ConstantValue类型的结构体,在赋值的时候使用这个ConstantValue进行赋值;如果该field字段并没有被final修饰,或者不是基本类型或者String类型,那么将在类构造方法<cinit>()中赋值。

常量池存有两种数据:字面量和符号引用

字面量又包含:文本字符串、final常量、基本数据类型的值等

符号引用包含:类的全限定名称、字段名称和描述符、方法名称和描述符

问题:

private int a = 10;//这样声明,常量池中没有10

private final int a = 10;// int声明为final,常量池中才有10,亦山的文章中也是用final字段进行演示的

但是将类型换成float,没有final也可以将字面量存进常量池,为什么?

private float f = 10f; //常量池中有10f

参考链接

带参数的jvm字节码指令 参数一般是指向常量池的索引如#4 #5 等

这个索引长度是2字节,当int类型字面量能够用2字节表达的时候,该字面量可以直接跟随字节码指令一起存放

该范围是-32768~32767

当int字面量为32768时,就会出现在常量池中了

结论:对于const系列命令和push系列命令操作范围之外的字面量。都放在常量池中的。