Java字节码详解系列之一--class文件格式简介

时间:2021-03-07 17:16:03
1,什么是字节码?

      首先,我们知道,Java语言是可以"write once,run anywhere",要做到这一点,就要在编写代码的时候让Java代码不能依赖计算机底层的机器指令,于是就出现了Java虚拟机来代替CPU执行Java编译后的代码,也就是"字节码"这种中间语言(IL)。Java编译后生成了class字节码,每一个Java类被编译后会生成一个对应的.class字节码文件,JVM运行时执行class字节码,将字节码实时翻译成所在平台的机器指令并运行。

2,字节码的格式

      JVM想要执行class字节码,那么class字节码就必需要有固定的文件格式。

      class字节码文件主要有两类数据:无符号数和表。无符号数用来表述数字,索引引用以及字符串等,无符号数主要使用u1,u2,u4及u8,分别代表1字节,2字节,4字节,8字节的无符号数。表是由多个无符号数及其他表组成的复合结构。

     一个class字节码文件主要由以下10个部分组成:

1,MagicNumber 用来标志文件是否为class文件,防止虚拟机加载非class文件而崩溃。

2,Version 该字段由2个2字节的字段组成,分别代表当前class文件的主次版本号。

3,Constant_pool 用来保存常量池信息,存放了字面常量(literal)和符号引用(symbolic references)。

     字面常量包含文本串和被声明为final的常量。符号引用包含类和接口的全局限定名,字段的名称和描述符,方法的名称和描述符。

4,Access_flag 主要保存当前类的访问权限。

5,This_class 主要保存当前类的全局限定名在常量池里的索引

6,Super_class 主要保存父类的全局限定名在常量池里的索引

7,Interfaces 主要保存当前类实现的接口列表,包含interfaces_count和interfaces[interfaces_count]。分别代表当前类实现的接口数量和接口的索引的数组。

8,Fields 主要保存当前类的成员列表,包含fields_count和fields[fields_count]。分别代表类变量(静态变量)和成员变量的数量之和。 字段详细信息的列表。

9,Methods 主要保存当前类的方法列表,包含methods_count和methods[methods_count]。分别代表该类或接口定义的方法的数量和方法信息的详细列表。

10,Attributes 主要保存类的attributes列表,包含attributes_count和attribute[attributes_count]。

用一个数据结构来表示class文件的格式 代码如下:

ClassFile {
    u4     magic;
    u2     minor_version;
    u2     major_version;
    u2     constant_pool_count;
    cp_info    contant_pool[constant_pool_count – 1];
    u2     access_flags;
    u2     this_class;
    u2     super_class;
    u2     interfaces_count;
    u2     interfaces[interfaces_count];
    u2    fields_count;
    field_info     fields[fields_count];`
    u2     methods_count;
    method_info    methods[methods_count];
    u2      attributes_count;
    attribute_info  attributes[attributes_count];
}

类似于C语言里的结构体。

3,了解字节码的好处

       了解字节码可以帮助我们更好的理解Java虚拟机的运行原理,以及更好的运用Java语言的特性。比如反射,就是JVM加载Java类的时候,将Java类的类元信息保存到内存中,这样在运行期直接就读取目标内存中的数据来获得相应的信息。

下一篇文章用一个Java类来具体介绍class字节码的字段作用。

好久没有写博客了,如果博客中有写的不对的地方,希望各位朋友积极指出,我会努力更正。