class文件的定义
class文件是一组以8位字节为基础的二级制流。各个数据项严格按照顺序紧凑的排列在class文件中,中间没有添加任何分隔符,整个class文件中存储的内容几乎全部都是程序运行的必要的数据,没有空隙存在
当遇到8位以上的空间的数据项时,则会按照高位在前方的方式分割成若干个8位字节进行存储
class文件有2种数据类型,分别是无符号数和表
无符号数属于基本数据类型,以u1,u2,u3,u4,u8来分别代表1字节,2个字节,,,可以用来描述数字、索引引用、数量值或者按照utf-8编码构成的字符串
表是由无符号数或者其他表作为数据项构成的复合数据类型
class文件的结构
魔数:每个class文件的头四个字节成为魔数,唯一的作用是确定这个文件是否为一个能被虚拟机接受的class文件,为(cafebaby)
class文件版本:接下来的四个字节是版本,java的版本号是从45开始的,(JDK1.0-1.1使用了45.0-45.3的版本号)高版本的JDK能兼容以前的class文件不能兼容以后的class文件
常量池:常量池主要存放字面量(文本字符串,声明为final的常量值),访问标志(类和接口的全限定名,字段的名称和描述符,方法的名称和描述符)
拿其中的一个constant_class_info表举例子
| 类型 | 名称 | 数量 |
| u1 | tag (tag代表这个常量属于哪种类型) | 1 |
| u2 | name_index (name_index是一个索引值,指向常量池中的一个类型常量) | 1 |
访问标志:紧接着的2个字节代表访问标志,用于识别一些类或者接口层面的信息,包括:class是类还是接口,是否是public 或者abstract类型等。
类索引、父类索引、接口索引集合:类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名,接口索引用来描述这个类实现了哪些接口
字段表集合:用于描述声明的变量,但不包括局部变量,可以包括的信息有字段的作用域(public,private,protected)、实例变量还是类变量(static修饰)、可变性(final)、并发可见性(volatile修饰符,是否强制从主内存读写)、字段名称。上述这些修饰符都可以用布尔型,用标志位来表示,但是字段名称不固定,只能引用常量池中的常量来描述。
方法表集合:与字段表集合描述的范畴相同
属性表集合:在class文件版本,字段表,方法表都可以携带自己的属性表集合
虚拟机范畴定义了如下属性
| 属性名称 | 使用位置 | 含义 |
| code | 方法表 | java代码编译成的字节码指令 |
| ConstantValue | 字段表 | final关键字定义的常量值 |
| Deprecated | 类、方法表、字段表 | 被声明为deprecated的方法和字段 |
| Exceptions | 方法表 | 方法抛出的异常 |
| EnclosingMethod | 类文件 | 当一个类是局部类或者是匿名类时才有这个属性值,用于标识这个类所在的外围方法 |
还有很多属性不一一列举,重点说code属性
code属性是class文件中最重要的属性,如果把一个java程序中的信息分为代码(方法体里面的代码)和元数据(类、字段、方法定义等)那么,在整个class文件中,code属性用于描述代码,所有其他属性用于描述元数据
本文介绍了Java Class文件的基本结构,包括其组成元素如魔数、版本号、常量池、访问标志等,以及如何存储和组织类的信息。同时,还详细解释了code属性的重要性和它在Class文件中的作用。

被折叠的 条评论
为什么被折叠?



