java class 文件格式解析

前言

大约5年前,我想研究cglib等字节码操作的相关类库来增强类。到了操作字节码的时候,发现无法继续。下去,只能放弃。

学习jvm代码,需要了解类的构成,对汇编和操作栈有更好的了解。只好重新学习编译原理、汇编等知识,再看jvm规范。现在更容易理解了。 .

类文件规范

Java 虚拟机编译后执行的代码使用平台无关(硬件和操作系统独立)方法

以二进制格式表示,并且经常(但不总是)存储为文件,因此这种格式称为类

文件格式。 Class 文件格式准确定义了类和接口的表示方式,包括特定于平台的对象文件格式中某些细节的约定

格式

相关文件

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_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];
}

接下来,我们开始分析每个字段是如何识别的

u4,u2是什么意思

u 无符号数后面的数字表示占用了多少字节

u4占用4个字节

u2占用2个字节

魔法占4个字,()

子版本号,2字节数字

主版本是一个2字节的数字

常量池的数量是一个2字节的数字

[-1] 常量池数组

获取标识2字节数字类名的索引,超类的名称索引接口数[]接口的数组字段数[]字段的数组方法数[]数方法的数组属性[] 属性数组如何自己解一个class文件

相信大部分第一个看到上面的协议的时候可以看一下,但是要自己去解析出各个字段的含义,

你不能开始,

读取类文件

p>

 FileInputStream in= new FileInputStream("d:/my.class");

读魔法,(魔法u4占用4个字节)

 byte[] bytes=new byte[4];
       in.read(bytes);

读取u2占用2个字节

 byte[] minorByte=new byte[2];
       in.read(minorByte);

读取 u2 需要 2 个字节

 byte[] majorVersion=new byte[2];
       in.read(majorVersion);

看到上面的分析,你明白了吗?其实还是很规律的,只要仔细阅读协议文档(多读几遍)

类文档最终分析是这样的

p>

ClassFile classFile = new ClassFile();
        PcBufferInputStream in = new PcBufferInputStream(new FileInputStream(fileName));
        classFile.setMagic(readMagic(in));
        classFile.setMinorVersion(readMinorVersion(in));
        classFile.setMajorVersion(readMajorVersion(in));
        classFile.setConstantPoolCount(readConstantPoolCount(in));
        classFile.setCpInfo(readCpInfo(in));
        classFile.setAccessFlags(readAccessFlags(in));
        classFile.setThisClass(readThisClass(in));
        classFile.setSuperClass(readSuperClass(in));
        classFile.setInterfacesCount(readInterfacesCount(in));
        // u2 interfaces interfaces_count
        classFile.setInterfaces(readInterfaces(in));
        // u2 fields_count
        classFile.setFieldsCount(readFieldsCount(in));
        // field_info fields fields_count
        classFile.setFields(readFields(in));
        // u2 methods_count 1
        // method_info methods methods_count
        classFile.setMethodsCount(readMethodsCount(in));
        classFile.setMethods(readMethods(in));
        // u2 attribute_count 1
        classFile.setAttributeCount(readAttributeCount(in));
        // attribute_info attributes attributes_count
        classFile.setAttributes(readAttributes(in));
        classFile.setPcRecord(recordMap);
        return classFile;

java类解析源码开源地址

如果喜欢,欢迎点赞

© 版权声明
THE END
喜欢就支持一下吧
点赞151赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容