关于class:解析Class文件示例

筹备

class文件是Java虚拟机惟一能够辨认的文件,依据Class文件咱们能够实现一个程序的运行,本节文章是自己解析一个根本Class文件的全过程,记录在此,心愿能提供给正在后退路上的同学作为辅助作用,上面是咱们要解析Class文件必要条件。

代码

以下是一个简略的Java类,一个公有变量,一个公开办法。

public class TestClass {

    private int a;

    public int increment() {

        return a + 1;
    }

}

将这个类编译为Class文件

筹备文本编辑器

自己应用Sublime Text关上咱们编译后的Class文件,次要目标是对照《Java虚拟机标准》中的Class文件的数据结构,上面是Sublime Text下载的网址。

Sublime Text

应用Sumlime关上Clas文件

《Java虚拟机标准》

咱们须要依照Java虚拟机标准中的数据结构,进行Class文件的十六进制码进行解析,所以这里须要依照官网,进行解析,以下是PDF在线链接,本节应用Java8版本。
Java虚拟机标准1.8

关上《Java虚拟机标准》

解析

咱们须要晓得一个Class文件由哪些数据结构组成,并排列进去,一项数据占几个字节,这些咱们都要晓得。
咱们首先须要记录,这个Class文件的大体构造,Class文件的数据结构及程序都是须要严格依照《Java虚拟机标准》生成的,找到《Java虚拟机标准》中的 “The Class File Format (Class文件格式)”中的Class构造项。

须要解释的是,这个ClassFile数据结构中的U2、u4别离代表两个字节、四个字节,其对应的左边的英文项,代表着其数据的常量项,Class文件是肯定依照这个构造进行构件的,《Java虚拟机标准》中也阐明了每一项的形容,自己联合官网整顿如下:

这个是自己整顿的Class文件的数据结构,有且只有这16项,具体的每一项,本文稍后都有解释。其实Class文件并不简单,只是Class中的援用比拟多,例如constant_pool_info中,这是一个常量池,池中记录着类、办法、字面量等描述符,是互相援用的形式。

javap查看class文件具体构造

应用javap查看文件构造,次要是为了供咱们于Class二进制形式进行比对时的一个参照物,以阐明咱们解读class文件时得出的论断是正确的。其余咱们须要确定咱们常量池中的程序以及所对应的常量池名。

javap -v TestClass.class

输入后果

依据javap所输入的数据结构,咱们失去了大抵的数据结构,剩下的咱们须要自行解析,并比对class中的十六进制数进行填写。这里采纳yaml文本格式进行填充,yaml格局能很直观的展现出一个对象的数据结构,并且采纳这种形式也能够很间接的将解析的值带入。针对咱们要解析的class文件,其中____是咱们要填充的数据,并且也进行了简略的正文阐明字段的含意及所占用的字节。构造如下:

class:
  #魔数 u4
  magic-number: ____
  #小版本号 u2
  minor-version: ____
  #大版本号 u2
  major-version: ____
  #常量池
  constant-pool:
    #常量池总数 u2
    count: ____
    #常量池(数组)
    constants: ____
  #拜访标记 u2
  access_flags: ____
  #以后类 u2
  this_class: ____
  #父类 u2
  super_class: ____
  #接口
  interface:
    # u2
    count: ____
    interfaces:
  #字段
  field:
    # u2
    count: ____
    fields: ____
  #办法
  method:
    # u2
    count: ____
    methods: ____
  #属性
  attributes:
    #u2
    count: ____
    attributes: ____

有了大抵的构造,咱们就能够开始解析之路啦!!

魔数

魔数项提供标识类文件格式的魔术数;它的值为0xCAFEBABE,这个值是固定的,每个文件都有属于本人的魔数,但在class文件中,CAFEBABE就是class文件的魔数,它占用4个字节。

随后将CAFEBABE填入咱们的yaml文件中:

小版本号

小版本号占用2个字节,因而,将class文件中的0000转换为十进制为0,所以小版本号为0;

大版本号

。。。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理