java 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个字节
- magic 占用4个字节,(ca fe ba be )

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

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

- constant_pool_count 常量池数目 2个字节的数字

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

- access_flags 访问标识 2个字节数字
- this_class class名称的索引,
- super_class 超类的名称索引
- interfaces_count 接口的数目
- interfaces[interfaces_count] 接口的数组
- fields_count 字段数目
- fields[fields_count] 字段的数组
- methods_count 方法的数目
- methods[methods_count] 方法的数组
- attributes_count 属性的数目
- attributes[attributes_count] 属性的数组
如何自己动手解一个class文件
相信大部分第一样看到上面的协议时候,能看弄,但是要自己动手解析出每个字段的含义出来,
就无法下手了,
- 读取class文件
FileInputStream in= new FileInputStream("d:/my.class");
- 读取 magic ,(magic u4 占用4个字节)
byte[] bytes=new byte[4];
in.read(bytes);
- 读取 minor_version u2 占用2个字节
byte[] minorByte=new byte[2];
in.read(minorByte);
- 读取 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 文件格式解析的更多相关文章
- (4) 深入理解Java Class文件格式(三)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21557357 首先, 让我们回顾一下关于class文件格式的之前两篇博客的主要内容. 在 ...
- Java 面试知识点解析(三)——JVM篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...
- (10) 深入了解Java Class文件格式(九)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22432599 经过前八篇关于class文件的博客, 关于class文件格式的内容也基本上讲 ...
- (9) 深入了解Java Class文件格式(八)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22205831 在本专栏的第一篇文章 深入理解Java虚拟机到底是什么 中, 我们主要讲解了 ...
- (8) 深入理解Java Class文件格式(七)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22091529 本专栏列前面的一系列博客, 对Class文件中的一部分数据项进行了介绍. 本 ...
- (7) 深入了解Java Class文件格式(六)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21888943 经过前几篇文章, 终于将常量池介绍完了, 之所以花这么大的功夫介绍常量池, ...
- (6) 深入理解Java Class文件格式(五)
前情回顾 本专栏的前几篇博文, 对class文件中的常量池进行了详细的解释. 前文讲解了常量池中的7种数据项, 它们分别是: CONSTANT_Utf8_info CONSTANT_NameAndTy ...
- (5) 深入理解Java Class文件格式(四)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21658415 前情回顾 在上一篇博客深入理解Java Class文件格式(三) 中, ...
- (3) 深入理解Java Class文件格式(二)
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/21487287 在上一篇文章 深入理解Java Class文件格式(一) 中, 介绍了c ...
随机推荐
- 4月8日 python学习总结 模块与包
一.包 #官网解释 Packages are a way of structuring Python's module namespace by using "dotted module n ...
- python 模块之 selenium 自动化使用教程
一.安装 pip install Selenium 二.初始化浏览器 Chrome 是初始化谷歌浏览器 Firefox 是初始化火狐浏览器 Edge 是初始化IE浏览器 PhantomJS 是一个无界 ...
- Nebula Graph 在网易游戏业务中的实践
本文首发于 Nebula Graph Community 公众号 当游戏上知识图谱,网易游戏是如何应对大规模图数据的管理问题,Nebula Graph 又是如何帮助网易游戏落地游戏内复杂的图的业务呢? ...
- 【网鼎杯2020青龙组】Web WriteUp
AreUSerialz 打开题目直接给出了源代码 <?php include("flag.php"); highlight_file(__FILE__); class Fil ...
- Git 工作流简介
1.概述 工作流有各式各样的用法,但也正因此使得在实际工作中如何上手使用增加了难度.这篇指南通过总览公司团队中最常用的几种 Git 工作流让大家可以上手使用. 在阅读的过程中请记住,本文中的几种工作流 ...
- VT 入门番外篇——初识 VT
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...
- ES6中数组新增的方法-超级好用
Array.find((item,indexArr,arr)=>{}) 掌握 找出第一个符合条件的数组成员. 它的参数是一个回调函数,对所有数组成员依次执行该回调函数. 直到找出第一个返回值为t ...
- 下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d"?
对于如下代码: String s1 = "a"; String s2 = s1 + "b"; String s3 = "a" + " ...
- Mybatis框架基础入门(六)--动态sql
主要是通过mybatis提供的各种标签方法实现动态拼接sql. 1.if标签 <!-- 根据条件查询用户 --> <select id="queryUserByWhere& ...
- 断言工具类之"判断条件不为空"
1 Assert.notNull(query, AssertConstants.NOT_NULL_MSG);