java class类文件结构解析(1)常量池解析

要理解class的结构,首先要先理解为什么我们需要它

Java之所以可以跨平台使用,本质上是在每个平台上都独立创建了一个Java虚拟机,于是这样便可以屏蔽不同指令集和操作系统带来的跨平台问题,但是显然我直接写出来的代码运行效率实在堪忧,而为了运行效率,Java虚拟机显然不能边编译边执行,而且这还会带来其他问题,如,恶意注入代码,于是我们先将代码编译,然后在各个平台通用

class本质上就是一段16进制的文件,随意使用16进制编辑器打开一个class文件,我这里使用的是UltraEdit,用它主要是因为百度搜索16进制编辑器第一个是它(o_o …)
java class类文件结构解析(1)常量池解析
首先,虚拟机需要检测前8个字节,你可以理解为对暗号,类似于虚拟机大喊一声,你是谁,class说,0101,我是座山雕差不多
前4个字节是固定的,专业术语叫魔数,Java的魔数就是cafebabe,翻译过来就是咖啡宝贝,其实就是说我是座山雕
但是光说我是座山雕是不行的,虚拟机还需要对一下声音,看看是不是真的座山雕
后4个字节表示class编译的Java大版本与小版本,00 00 35 00的意思就是我是用jdk9编译的class文件
虚拟机有一份又长又宽的名单,一看,在名单上,说明“声音”对上了,就认为你是真的座山雕,就放过了,但是如果我换最新的jdk11,虚拟机一看,不在名单上,那就对不起了,暗号对不上,溜了溜了ε=ε=ε=┏(゜ロ゜;)┛
暗号对上了,就应该发电报了,00 16表示座山雕这里有16+6一共22个情报需要放到常量池里,情报肯定是需要加密的,于是座山雕就用数字代替情报的类型,
0A表示这是一个类中方法的符号调用,00 04表示这个类的描述符是常量池里的第4个常量,打开javap将这段class代码解析,看看第4个常量是谁
java class类文件结构解析(1)常量池解析
可以看到,第四个常量指向第23个常量,也就是java/lang/Object,很明显,第一个情报是一个Object类,它的类位置被放在常量池中的第4个位置,而它又指向第23个常量也就是Object中存放的位置java/lang/Object,而00 12表示这个类的名字指向常量池的第18个值上,也就是SourceFile,也就是说,这是一个叫SourceFile的Object类
那么第一个常量就解析出来了,是一个叫SourceFile的Object类,剩下的解析过程其实差不多,要注意的是,常量分两种,一种是引用,即我上面分析的一个叫SourceFile的Object类,还有一种是字面量,这才是真正的常量,引用就指向它们,还有就是所有常量的数据结构类型其实都不一致,唯一相同的是都会在最开始有一字节的标志位,标识这是什么常量,下面是常见常量类型

类型 标志 描述
CONSTANT_Utf8_info 1 UTF-8编码的字符串
CONSTANT_Integer_info 3 整形字面量,boolean、byte、char、short等类型都用int存放
CONSTANT_Float_info 4 浮点型字面量
CONSTANT_Long_info 5 长整型字面量
CONSTANT_Double_info 6 双精度浮点型字面量
CONSTANT_Class_info 7 类或接口的符号引用
CONSTANT_String_info 8 字符串类型字面量
CONSTANT_Fieldref_info 9 字段的符号引用
CONSTANT_Methodref_info 10 类中方法的符号引用
CONSTANT_InterfaceMethodref 11 接口中方法的符号引用
CONSTANT_NameAndType_info 12 字段或方法的部分符号引用

数据结构实在太多了,我以后有时间再来补上吧溜了溜了ε=ε=ε=┏(゜ロ゜;)┛