前言
为什么要学习Java字节码呢,因为我们学的是插桩字节码技术,这块技术的根底就是字节码,要学会字节码的阅读和字节码的编写,虽然现在很多工具可以帮我们阅读和编写,但最根本的知识还是要理解的。万层楼高从地起,打好基础是关键。
字节码和ClassFile关系
ClassFile是以.class结尾的二进制文件,而该二进制文件中存储的内容就是16进制的Java字节码,在我们学习的插桩技术中,本质就是修改Java字节码文件,也就是要修改ClassFile,读懂Java字节码的基础就是要读懂ClassFile的意思
ClassFile解读
ClassFile是字节码存储文件,规定了规范,我们只需要按照规范的内容进行解析和解读即可知道表达的意思,我们通过简单的例子来演示
1、Hello Word
简单的写一段HelloWord代码,
package hensen;
public class Demo {
    public static void main(String[] args) {
        System.out.println("Hello World.");
    }
}
通过javac生成class文件,通过Editor010读取里面的十六进制格式的内容

通过javap -v 查看class文件的结构,这个接口是java帮我们打印出来的,下面我们就看看怎么解析的

2、ClassFile结构解析
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];
}
- u1: 表示占用1个字节,2个16进制字符
- u2: 表示占用2个字节,4个16进制字符
- u4: 表示占用4个字节,8个16进制字符
- u8: 表示占用8个字节,16个16进制字符
3、字节码解析案例
(一)魔数
CAFE BABE
第1 - 4个字节表示magic魔数,魔数的作用是Class文件的标识,虚拟机会判断这个文件是否为一个能被虚拟机接受的Class文件
(二)文件版本
0000 0034
- 第5 - 6个字节表示minor_versionJDK的次版本号
- 第7 - 8个字节表示major_versionJDK的主版本号
| JDK版本 | 次版本号 | 主版本号 | 十进制 | 
|---|---|---|---|
| JDK1.7 | 0000 | 0033 | 51 | 
| JDK1.8 | 0000 | 0034 | 52 | 
(三)常量池
接着是到了常量池的解析
001D
- 前2个字节表示常量池个数,其值为29,表示一共有29 - 1 = 28个常量
- 后N个字节表示常量池的具体内容
确定常量池数量后,要确定常量池内容
cp_info {
    u1 tag;
    u1 info[];
}
常量池的内容都会有个统一个格式,前1个字节表示类型,后面的字节表示常量池的值
0A 00 06 00 0F
| 字段 | 长度 | 字段值 | 说明 | 
|---|---|---|---|
| CONSTANT_Methodref_info | u1 | tag(0x0A) | 类中方法的符号引用 | 
| — | u2 | class_index | 指向声明方法的类描述符CONSTANT_Class_info的索引项 | 
| — | u2 | name_and_type_index | 指向名称及类型描述符CONSTANT_NameAndType的索引项 | 
通过常量池寻表,可以发现,该常量项第2-3个字节表示类信息,第4-5个字节表示名称及类描述符
- class_index:0x06(#6)
- name_and_type_index:0x0F(#15)



















