如何解析Java的class文件格式?

2026-05-19 22:291阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计959个文字,预计阅读时间需要4分钟。

如何解析Java的class文件格式?

前言:五年前,我渴望研究Java Assistant、Cglib等字节码操作的相关类库,以期对class进行增强。当需要操作字节码时,发现无法继续下去,看不懂,只能放弃。+ 学习JVM字节码,需要理解。

前言

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

Class文件规范

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

相关文档
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] 常量池数组

如何解析Java的class文件格式?

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

gitee.com/venus-suite/java-classViewer

如果喜欢,欢迎stars 哦

本文共计959个文字,预计阅读时间需要4分钟。

如何解析Java的class文件格式?

前言:五年前,我渴望研究Java Assistant、Cglib等字节码操作的相关类库,以期对class进行增强。当需要操作字节码时,发现无法继续下去,看不懂,只能放弃。+ 学习JVM字节码,需要理解。

前言

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

Class文件规范

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

相关文档
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] 常量池数组

如何解析Java的class文件格式?

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

gitee.com/venus-suite/java-classViewer

如果喜欢,欢迎stars 哦