您的位置:首页 > 其它

JVM Class 文件结构详解一

2014-09-22 22:27 281 查看
Class文件的存储结构使得Java虚拟机实现了语言无关性,不同的语言,如java、groovy等程序语言通过编译可以转化为存储字节码的Class文件,从而使得Class文件在虚拟机中运行。

1、Class文件的结构

Class文件是一组以8位字节为单位的二进制流,各数据项严格按照顺序紧凑的排列在Class文件之中,中间无任何分隔符号。根据JVM Specification规定,Class文件格式采用一种类似于C语言结构体的伪结构来存储。这种伪结构中只有两种数据类型:无符号数和表。

无符号数:基本数据类型,以u1、u2、u4和u8分别代表1个字节、2个字节、4个字节和8个字节的无符号数,用于描述数字、索引引用、数量值等。

表:由多个无符号数或其他表作为数据项构成的复合数据类型,以_info结尾,用于描述有层次关系的复合机构的数据。

下图是Class文件格式:




为了方便解释,编写如下简单代码:

package cn.com.yy;

/**
 * Class文件结构
 * @author yy
 * @time 2014-9-22 下午9:57:50
 */
public class ClassFileTest {

	private int count;
	
	public int returnValue(){
		return count;
	}
}


(1)magic

magic,称之为魔数,是Class文件的前4个字节,作用为用于确定这个文件是否为一个能被虚拟机接受的Class文件。值为0xCAFEBABE。上述代码编译后,打开Class文件,显示如下图:




可以看出,Class文件的前4个字节为magic的值。

(2)Class文件的版本

接下来的第5个字节和第6个字节是Class文件的次版本号,第和第8字节为主版本号,如下图:




从图中可以看出,次版本号为0x0000,主版本号为0x0032,主版本号为十进制的50,说明该Class文件可以被JDK1.6或以上版本的虚拟机执行。下图为Class文件的版本号:




从图中可以看出,从JDK1.3后,就没有此版本号了,只有主版本号。

需要注意的是:某个版本的JVM能接受Class文件的最大主版本号不能超过对应JDK带对应target参数编译出来的Class文件的版本号。举例:JVM1.4能接受的Class文件的主版本号不能超过1.4JDK -target 1.4时编译出的Class文件的主版本号:48。

(3)常量池个数和常量池

接下来为2个字节的常量池个数:




该程序的constant_pool_count为0x0016,即十进制的22,代表着常量池中有21项常量,索引为1~21(索引为0的不算)。具体的常量值可以通过命令javap -verbose className获悉,如下:




在字节码文件中显示的区域为下:




途中红色线框包含的区域为常量区。

对于常量池,池中的每一个项常量都是一个表,共有11种结构不通的表结构数据。如下图所示:




上图中的每个表有一共同特点:表开始的第一位是一个u1类型的标志位(tag,取值为1,。。。12,没有2)。且每个表的结构都不同,下图中列出了每种数据表的结构,如下图所示:


类型

项目
类型
描述
CONSTANT_Utf8_info
tag
u1

值为1

length
u2

UTF-8编码的字符串占用的字节数

bytes
u1
长度为length的UTF-8编码的字符串

CONSTANT_Integer_info
tag
u1
值为3

bytes
u4
按照高位在前存储的int值

CONSTANT_Float_info
tag
u1
值为4

bytes
u4
按照高位在前存储的float值

CONSTANT_Long_info
tag
u1
值为5

bytes
u8
按照高位在前存储的long值

CONSTANT_Double_info
tag
u1
值为6

bytes
u8
按照高位在前存储的double值

CONSTANT_Class_info
tag
u1
值为7

index
u2
指向全限定名常量项的索引

CONSTANT_String_info
tag
u1
值为8

index
u2
指向字符串字面量的索引

CONSTANT_Fieldref_info
tag
u1
值为9

index
u2
指向声明字段的类或接口描述符CONSTANT_Class_info的索引项

index
u2
指向字段描述符CONSTANT_NameAndType_info的索引项

CONSTANT_Methodref_info
tag
u1
值为10

index
u2
指向声明方法的类描述符CONSTANT_Class_info的索引项

index
u2
指向名称及类型描述符CONSTANT_NameAndType_info的索引项

CONSTANT_InterfaceMethodref_info
tag
u1
值为11

index
u2
指向声明方法的接口描述符CONSTANT_Class_info的索引项

index
u2
指向名称及类型描述符CONSTANT_NameAndType_info的索引项

CONSTANT_NameAndType_info
tag
u1
值为12

index

u2
指向该字段或方法名称常量项的索引

index
u2
指向该方法或方法描述符常量项的索引

针对JVM Class文件结构中的其他内容请参考文章JVM Class 文件结构详解二
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: