java class 文件格式解析

java

前言

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

学习jvm字码,需要理解class的组成方式,对汇编,操作栈比较了解,无奈,只好重新学习编译原理,汇编等知识,再来看jvm规范,现在理解起来,容易很多了。

class文件规范">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 )

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

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

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

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

  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 哦

以上是 java class 文件格式解析 的全部内容, 来源链接: utcz.com/z/395050.html

回到顶部