Java类文件结构详解

您所在的位置:网站首页 java类文件结构需要记住吗 Java类文件结构详解

Java类文件结构详解

2024-02-27 20:00| 来源: 网络整理| 查看: 265

1. ClassFile结构

类文件由单个ClassFile结构组成 全局规范:

任何一个Class文件都对应着唯一一个类或接口的定义信息,但反过来说,类或接口并不一定都得定义在文件里(譬如类或接口也可以通过类加载器直接生成)。本章中,只是通俗地将任意一个有效的类或接口所应当满足的格式称为“Class文件格式”,实际上它并不一定以磁盘文件的形式存在。“Class文件”应当是一串二进制的字节流,无论以何种形式存在。

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,当遇到需要占用8位字节以上空间的数据项时,则会按照**高位在前(Big-Endian)**的方式分割成若干个8位字节进行存储。无符号数据类型最大占8个字节。

Class文件中存储数据的类型:无符号数和复合数据类型。

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

复合数据类型:如下图中constantpool,可以看成是多个cpinfo项(常量项)组成的表。

文件中的数据项,无论是顺序还是数量,甚至于数据存储的字节序(Byte Ordering,Class文件中字节序为Big-Endian)这样的细节,都是被严格限定的,哪个字节代表什么含义,长度是多少,先后顺序如何,都不允许改变。

ClassFile { u4 magic; //Class文件的标志 u2 minor_version; //Class的小版本号 u2 major_version; //Class的大版本号 u2 constant_pool_count; //常量池的数量 cp_info constant_pool[constant_pool_count-1]; //常量池 u2 access_flags; //Class的访问标记 u2 this_class; //当前类 u2 super_class; //父类 u2 interfaces_count; //接口 u2 interfaces[interfaces_count]; //一个类可以实现多个接口 u2 fields_count; //Class文件的字段属性 field_info fields[fields_count]; //一个类会可以有个字段 u2 methods_count; //Class文件的方法数量 method_info methods[methods_count]; //一个类可以有个多个方法 u2 attributes_count; //此类的属性表中的属性数 attribute_info attributes[attributes_count]; //属性表集合 } 1.1 魔数 u4 magic; //Class文件的标志

The magic item supplies the magic number identifying the class file format; it has the value 0xCAFEBABE.

每个 Class 文件的头四个字节称为魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接收的 Class 文件。 程序设计者很多时候都喜欢用一些特殊的数字表示固定的文件类型或者其它特殊的含义。

1.2 Class文件版本 u2 minor_version; //Class的小版本号 u2 major_version; //Class的大版本号

紧接着魔数的四个字节存储的是 Class 文件的版本号:第五和第六是次版本号,第七和第八是主版本号。 高版本的 Java 虚拟机可以执行低版本编译器生成的 Class 文件,但是低版本的 Java 虚拟机不能执行高版本编译器生成的 Class 文件。

1.3 类文件常量池 u2 constant_pool_count; //常量池的数量 cp_info constant_pool[constant_pool_count-1]; //常量池

紧接着主次版本号之后的是常量池,常量池的数量是 constantpoolcount-1(常量池计数器是从1开始计数的,将第0项常量空出来是有特殊考虑的,索引值为0代表“不引用任何一个常量池项”)。

常量池主要存放两大常量: 字面量和符号引用。字面量比较接近于 Java 语言层面的的常量概念,如文本字符串、声明为 final 的常量值等。而符号引用则属于编译原理方面的概念。包括下面三类常量:

类和接口的全限定名

字段的名称和描述符

方法的名称和描述符

哪些字面量会进入常量池中?

字符串常量(final修饰的成员变量 局部变量不行)非final修饰的float、double、long基本类型 public class Test { private int int_num = 12; private byte byte_num = 121; private short short_num = 30; private char char_num = 'a'; private float float_num = 45.3f; //字面量 private double double_num = 39.8; //字面量 private long long_num = 2323L; //字面量 private boolean boolean_flag = true; private long long_delay_num; public void test() { final int a_test = 123; String b_test = "b_test_part"; //字面量 this.long_delay_num = 5555L; //字面量 } }

所有的常量项在常量池表都有以下结构:

cp_info { u1 tag; u1 info[]; }

以一个字节的tag开始,代表当前常量属于哪种常量类型,共有14种类型(见***Table. Constant pool tags***)。 info数组的内容格式随tag不同而不同,每个tag字节后必须跟两个或多个字节,以提供有关特定常数的信息。 Table. Constant pool tags

| Constant Type | Value | 描述 | | — | — | — | | CONSTANT_Class | 7 | 类或接口的符号引用 | | CONSTANT_Fieldref | 9 | 字段的符号引用 | | CONSTANT_Methodref | 10 | 类中方法的符号引用 | | CONSTANT_InterfaceMethodref | 11 | 接口中方法的符号引用 | | CONSTANT_String | 8 | 字符串类型字面量 | | CONSTANT_Integer | 3 | 整型字面量 | | CONSTANT_Float | 4 | 浮点型字面量 | | CONSTANT_Long | 5 | 长整型字面量 | | CONSTANT_Double | 6 | 双精度浮点型字面量 | | CONSTANT_NameAndType | 12 | 字段或方法的符号引用 | | CONSTANT_Utf8 | 1 | UTF-8编码的字符串 | | CONSTANT_MethodHandle | 15 | 方法句柄 | | CONSTANT_MethodType | 16 | 方法类型 | | CONSTANT_InvokeDynamic | 18 | 动态方法调用点 |

1.3.1 The CONSTANTClassinfo Structure

CONSTANT_Class_info { u1 tag; u2 name_index; }

nameindex: 指向CONSTANTUtf8_info常量项的合法索引值,表示一个二进制类或接口名(Binary Class and Interface Names)。

For example, the normal binary name of class _Thread is java.lang.Thread. In the internal form used in descriptors in the class file format, a reference to the name of class Thread is implemented using a CONSTANT_Utf8_info structure representing the string java/lang/Thread._

For example, the class name representing the two-dimensional array type _int[][] is [[I, while the class name representing the type Thread[] is [Ljava/lang/Thread;._ _An array type descriptor is valid only if it represents 255 or fewer dimensions.

1.3.2 The CONSTANTFieldrefinfo, CONSTANTMethodrefinfo, and CONSTANTInterfaceMethodrefinfo Structures

CONSTANT_Fieldref_info { u1 tag; u2 class_index; u2 name_and_type_index; } CONSTANT_Methodref_info { u1 tag; u2 class_index; u2 name_and_type_index; } CONSTANT_InterfaceMethodref_info { u1 tag; u2 class_index; u2 name_and_type_index; } class_index

The value of the class_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure (§4.4.1) representing a class or interface type that has the field or method as a member.

The class_index item of a CONSTANT_Methodref_info structure must be a class type, not an interface type.The class_index item of a CONSTANT_InterfaceMethodref_info structure must be an interface type.The class_index item of a CONSTANT_Fieldref_info structure may be either a class type or an interface type.nameandtype_index

The value of the name_and_type_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_NameAndType_info structure (§4.4.6). This constant_pool entry indicates the name and descriptor of the field or method.

In a CONSTANT_Fieldref_info, the indicated descriptor must be a field descriptor (§4.3.2). Otherwise, the indicated descriptor must be a method descriptor (§4.3.3).

If the name of the method of a CONSTANT_Methodref_info structure begins with a ‘



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3