前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Class类文件结构

Class类文件结构

作者头像
每天学Java
发布2020-06-02 09:58:26
8910
发布2020-06-02 09:58:26
举报
文章被收录于专栏:每天学Java每天学Java

我们都知道Java虚拟机不和包括Java在的任何语言绑定,它只与Class文件这种特定的二进制文件格式所关联。而Class文件是由java文件经过javac编译器编译后生成的。

01

Class类文件结构

在深入理解Java虚拟机一书中是先介绍概念然后具体分析,这里我就反过来描述,我们先看一下class文件,这里我打开一个本地被编译过的class文件,我们看到它是乱码的。

命令:vim classbean/support/zj/CreatePMSWF.class

效果:

我们使用输入:%!xxd(:%!xxd是把文件转换为16进制来显示)

上面图片出现的一连串数据都是什么意思呢?

首先我们看到最开始的四个字节:0xcafebabe,这个叫魔数(Magin Number),它的唯一作用是用于确定这个文件是否为一个能被虚拟机接受的Class文件,换句话说如果一个文件不是以0xCAFEBABE开头,那它就肯定不是Java class文件。

占4个字节的魔数之后第五和第六个字节表示次版本号(Minor Version),如上图中的00和00;而第七和第八个字节表示主版本号(Major Version)。Java的版本是从45开始的,也就是0x002D,上图中的版本号就是0x0032了,此外JDK1.1之后每个JDK大版本发布主版本向上加一(JDK1.0~1.1使用了45.0和45.3),且高版本的JDK能兼容低版本的Class文件,但是不能低版本JDK运行高版本编译后的Class文件,即时文件格式并未发生任何变化,Java虚拟机也必须拒绝执行超过其版本号的Class文件。

跟着主版本号后面的字节代表常量池的入口,它是Class文件中第一个出现表类型的数据项目。

这里我们就需要引入一些概念了:

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

无符号数属于基本的数据类型,以u1,u2,u4,u8来分别代表一个字节,2个字节,4个字节,8个字节的无符号数,无符号数可以用来描述数字,索引引用,数量值或者按照UTF-8编码构成字符串值

表是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有的表都习惯性以_info结尾)。

那么后面01c2....怎么解释呢?首先常量池中常量的数量是不确定的,所有常量池的入口放置一项u2(2个字节)类型的数据表示数值:即0x01c2=450。但是这个数值的计数是从1开始的,所有由449项常量,不从0开始计数是在特殊情况下表示“不引用任何常量池项目”的含义,除了常量池其他集合类型都是从0开始计数。

这里继续引用一些概念:

常量池之中主要存放两大类常量:

字面量: 比较接近于Java语言层面的常量概念,如文本字符串、被声明为final的常量值等 符号引用: 属于编译原理方面的概念,包括了下面三类常量:

1.  类和接口的全限定名 2.  字段的名称和描述符 3.  方法的名称和描述符

那常量池入口之后的十六进制表示什么呢?我们首先看第一项常量的标识位:0x0a=10,它属于CONSTANNT_METHODREF_info(表),类中方法的符号引用。

常量池中14种常量项的结构总表(共有14种(JDK1.7前只有11种)结构各不相同的表结构数据。这14种表都有一个共同的特点,即均由一个u1类型的标志位开始,可以通过这个标志位来判断这个常量属于哪种常量类型)

图中tag是标识位,也是对应十六进制转换十进制后对应的表。

既然0x0a=10属于CONSTANNT_METHODREF_info(表),那么其后的四个字节分别如上表一样0x008b指向CONSTANT_Class_info和0x00f1执行CONSTANT_NameAndType的索引。

再往后分析就是根据上面表对应的字节同class图中队十六进制数据进行比对。这里我们就不继续了,我们可以通过Javap命令分析字节码工具,来看一下这个类。

最后我们再来看一些概念性的东西:

Java代码在进行Java编译的时候,并不像C和C++那样有"连接"这一步骤,而是在虚拟机加载Class文件的时候进行动态连接。也就是说,在Class文件中不会保存各个方法和字段的最终内存布局信息,因此这些字段和方法的符号引用不经过转换的话是无法被虚拟机使用的。当虚拟机运行时,需要从常量池获得对应的符号引用,再在类创建时或运行时解析并翻译到具体的内存地址之中。

Class文件是一组以8字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑排列在class文件中,中间没有任何分隔符,这使得class文件中存储的内容几乎全部是程序运行的必要程序。

Java虚拟机规范规定,Class文件格式采用类似C语言结构体的伪结构来存储数据,这种结构只有两种数据类型:无符号数和表

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 每天学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档