ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java class 文件格式解析

2022-04-16 17:32:45  阅读:221  来源: 互联网

标签:count classFile java 字节 fields u2 文件格式 class


前言

大约5年前,想研究javaassistant,cglib等字节码操作的相关类库,来对class进行增强,当要到要操作字节码的时候,发现无法继续下去了,只能放弃。
学习jvm字码,需要理解class的组成方式,对汇编,操作栈比较了解,无奈,只好重新学习编译原理,汇编等知识,再来看jvm规范,现在理解起来,容易很多了。

Class文件规范

编译后被 Java 虚拟机所执行的代码使用了一种平台中立(不依赖于特定硬件及操作系统的)
的二进制格式来表示,并且经常(但并非绝对)以文件的形式存储,因此这种格式被称为 Class
文件格式。Class 文件格式中精确地定义了类与接口的表示形式,包括在平台相关的目标文件格
式中一些细节上的惯例

相关文档
https://docs.oracle.com/javase/specs/jvms/se15/html/jvms-4.html

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个字节

  1. magic 占用4个字节,(ca fe ba be )

image

  1. minor_version 子版本号 ,2个字节数字
    image

  2. major_version 主版本好 2个字节的数字

image

  1. constant_pool_count 常量池数目 2个字节的数字

image

  1. constant_pool[constant_pool_count-1] 常量池数组

image

  1. access_flags 访问标识 2个字节数字
  2. this_class class名称的索引,
  3. super_class 超类的名称索引
  4. interfaces_count 接口的数目
  5. interfaces[interfaces_count] 接口的数组
  6. fields_count 字段数目
  7. fields[fields_count] 字段的数组
  8. methods_count 方法的数目
  9. methods[methods_count] 方法的数组
  10. attributes_count 属性的数目
  11. attributes[attributes_count] 属性的数组

如何自己动手解一个class文件

相信大部分第一样看到上面的协议时候,能看弄,但是要自己动手解析出每个字段的含义出来,
就无法下手了,

  1. 读取class文件
 FileInputStream in= new FileInputStream("d:/my.class");
  1. 读取 magic ,(magic u4 占用4个字节)
 byte[] bytes=new byte[4];
       in.read(bytes);
  1. 读取 minor_version u2 占用2个字节
 byte[] minorByte=new byte[2];
       in.read(minorByte);
  1. 读取 major_version u2 占用2个字节
 byte[] majorVersion=new byte[2];
       in.read(majorVersion);

看到上面的解析,是否明白了,其实还是很有规律的,只要你认真看协议文档(要看好多遍才行)

最终解析class 文档就是这样的

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 class 解析源码开源地址

https://gitee.com/venus-suite/java-classViewer

如果喜欢,欢迎stars 哦

标签:count,classFile,java,字节,fields,u2,文件格式,class
来源: https://www.cnblogs.com/tomj2ee/p/16153238.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有