一、Class文件
Test.java
public class Test{
private int count;
public int inc(){
return count++;
}
}
vim -b Test.class
输入 :%!xxd
图一
java反编译
javap -v -l -c Test.class
图二
二、Class文件解析
1、Class文件结构
1、魔数
魔数magic是Class文件的标记,在class文件最开头四个字节,其十六进制值是cafe babe,参见图一,这个标记是用来告诉虚拟机这是Class文件。
2、Class文件版本
小版本号(minor_version)、大版本号(major_version)表示当前Class文件由哪个版本的编译器产生,图一major_version 为55表示编译器版本是JDK11, JDK编译器的版本和Class文件的大版本对应关系如下
50-JDK6、51-JDK7、52-JDK8、53-JDK9、54-JDK10、55-JDK11
高版本JVM可以执行低版本Class,低版本JVM不能执行高版本Class。
3、常量池
图二,可以看到Constant pool常量池下有18个常量,对应图一第一行的第9,10字节值为【0013】常量数量。
常量池存放两类常量:字面量和符号引用。
这个太复杂,不仔细讲了,因为我也不太懂 :)
常量池的作用是:常量池是用来保存常量一个中间场所,在JVM运行时把常量池中的常量加载到内存中
4、Class访问标记
图二第五行
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
ACC_PUBLIC 表示是Public的类。
5、方法
图二第39行~53行
stack=4,locals=1,args_size=1
stack=4:操作数栈最大深度为4,用于保存计算过程中间结果,同时做为计算过程变量临时存储空间。
locals=1:本地变量表大小
args_size=1:方法参数个数
方法指令解析
0: aload_0:从局部变量表加载到操作数栈
1: dup:dup指令可以复制操作数栈栈顶的一个字
2: getfield:获取变量count的值
5: dup_x1:复制栈顶部一个字长的内容,
然后将复制内容及原来弹出的两个字长的内容压入栈
6: iconst_1 不细说,因为我也不懂 :)
7: iadd:加运算
8: putfield 将结果赋给局部变量
11: ireturn 返回