四、类文件结构

详见: http://wiki.jikexueyuan.com/project/java-vm/class.html

 


 

Class 文件中各数据项是按照上表的顺序和数量被严格限定的,每个字节代表的含义、长度、先后顺序都不允许改变。

 

1、 magic version

每个 Class 文件的头 4 个字节称为魔数(magic),它的唯一作用是判断该文件是否为一个能被虚拟机接受的 Class 文件。它的值固定为 0xCAFEBABE。紧接着 magic 4 个字节存储的是 Class 文件的次版本号和主版本号,高版本的 JDK 能向下兼容低版本的 Class 文件,但不能运行更高版本的 Class 文件。

 

2、constant_pool

major_version 之后是常量池(constant_pool)的入口,它是 Class 文件中与其他项目关联最多的数据类型,也是占用 Class 文件空间最大的数据项目之一。

 

常量池中主要存放两大类常量:字面量和符号引用。字面量比较接近于 Java 层面的常量概念,如文本字符串、被声明为 final 的常量值等。而符号引用总结起来则包括了下面三类常量:

  • 类和接口的全限定名(即带有包名的 Class 名,如:org.lxh.test.TestClass
  • 字段的名称和描述符(privatestatic 等描述符)
  • 方法的名称和描述符(privatestatic 等描述符)

 

虚拟机在加载 Class 文件时才会进行动态连接,也就是说,Class 文件中不会保存各个方法和字段的最终内存布局信息,因此,这些字段和方法的符号引用不经过转换是无法直接被虚拟机使用的。当虚拟机运行时,需要从常量池中获得对应的符号引用再在类加载过程中的解析阶段将其替换为直接引用,并翻译到具体的内存地址中

 

3、 ConstantValue 属性

如果同时使用 final static 修饰一个变量(即全局常量),并且这个变量的数据类型是基本类型或 String 的话,就生成 ConstantValue 属性来进行初始化(编译时 Javac 将会为该常量生成 ConstantValue 属性,在类加载的准备阶段虚拟机便会根据 ConstantValue 为常量设置相应的值),如果该变量没有被 final 修饰,或者并非基本类型及字符串,则选择在方法中进行初始化。

 

下面简要说明下 finalstaticstatic final 修饰的字段赋值的区别:

 

  • static 修饰的字段在类加载过程中的准备阶段被初始化为 0 null 等默认值,而后在初始化阶段(触发类构造器)才会被赋予代码中设定的值,如果没有设定值,那么它的值就为默认值。
  • final 修饰的字段在运行时被初始化(可以直接赋值,也可以在实例构造器中赋值),一旦赋值便不可更改;
  • static final 修饰的字段在 Javac 时生成 ConstantValue 属性,在类加载的准备阶段根据ConstantValue的值为该字段赋值,它没有默认值,必须显式地赋值,否则 Javac 时会报错。可以理解为在编译期即把结果放入了常量池中。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值