手写Java虚拟机(三)—— 解析class类文件

本文深入解析Java Class文件的结构,包括魔数、版本号、常量池等关键部分,通过实例tt.class展示如何理解Class文件的存储方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

唔。。在解析前,先给大家介绍下Class类文件结构吧。

Class文件格式采用的是一种类似C语言结构体的伪结构来存储数据,这种伪结构中只有两种类型:无符号数和表。

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

表是由多个无符号数或者其他表作为数据构成的复合数据类型,所有表都习惯性以“_infor”结尾,整个Class文件本质上就是一张表。

下面是Class文件的结构。

 Class文件就是严格按照这个格式来存储数据的。

唔。。多说无益,直接上例子吧。

public class tt {
    private int m;

    public int inc() {
        return m + 1;
    }
}

这个我们tt.java的代码,下面,我们就要把这个tt.java编译后的tt.class文件,给解析出来。

首先,javac 命令tt.java编译成tt.class

然后,用16进制查看器查看tt.class文件

这就是class文件了,下面我们按照上面的class文件结构来一步一步分析。

1.magic魔数和minor_version、major_version。

每个class文件的头4个字节称为魔数,它的唯一作用就是确定这个文件是能被jvm解析的class文件。很多不同格式的文件都是通过魔数来进行识别的,比如gif或者jpeg等文件头中都有魔数。

class文件的魔数是固定的值为:0xCAFEBABA,这和我们class文件结构图中的描述一致,是u4类型的数据。

之后是Class文件的版本号,minor_version是次版本号,值为0x0000,major_version是主版本号,值分别是0x0034,也就是十进制的52,也就是JDK1.8版本编译的。

下面是Class文件版本号

2.常量池

接着版本号之后的是常量池:constant_pool_count,constant_pool。

constant_pool_count代表的是常量池的数量,这个数量的计数是从1开始,而不是0开始的。

在该例子中,常量池数量为十六进制数0x0013,即十进制的19,因为计数是从1开始,所以,这常量池的数量为19-1=18。

跟在常量池数量之后的是具体的常量池内容。常量池中主要存放两大类常量:字面量和符号引用,字面量也就是字符串、final类型的常量值等,符号引用则是编译方面的概念。

在JDK1.7之前一共有11种结构各不相同的表结构。这些表都有一个共同特点,第一位是u1类型的标志位,用来标致是哪种类型的常量。下面是标志相对应的常量类型。

详细的常量类型结构我这里就不写了,这里只写例子中所用到的类型结构。建议大家参考《深入理解java虚拟机》第6章。

唔。。。。

写到这里突然不想写了,因为class类文件结构不难,同时,觉得自己这篇博客写的没什么实际意义。

第一,写给自己做总结吧,也没总结到啥,因为真的不难,没啥好总结的感觉,

第二,写给大家看吧,大家还不如看书,书里讲的很详细,要是有不懂的,可以留言交流。

唔。。

也可以参考我写的解析代码:https://github.com/ZheBigFish/myjvm,ch03写的就是类文件解析

唔,建议大家多看书。

最后,本文参考自《深入理解java虚拟机》第6章。

OK,此贴终结。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值