路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码

我之前写了一篇关于class文件重要性的 , 并且从宏观角度解释了下class文件的构成 , 文章直通车(www.juejin.im/post/684490…)
这篇我们就深入的了解一下class文件的各项内容 , 先看看字节码的样子 。
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
以下对字节码的分析 , 就以这个简单的例子为主 。 所有的字节码都是cafebabe开头 , java一直给咖啡代言 , 可说是咖啡的忠实粉丝了 , 就像我爱大幂幂一样 , 撒花~
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
class文件可真是个小机灵鬼 , 正是class文件+JVM组合 , 各种语言编写的代码只要能编译成JVM可以正确识别的class文件 , 就可以运行在JVM上面 , 才使得JAVA语言乃至所有可以运行在JVM上的语言实现了平台无关性 , JVM更是可以向语言无关性发展 , class文件的使命就是教JVM怎么运行 , 运行什么 。
class文件是一组以8位字节为基础单位的十六进制流 , 中间没有任何分隔符 , 细细品这句话 。 正是因为class文件是流式的 , 中间没有任何分隔符所以class文件里面的数据项在顺序和数量上面是严格限定的 , 每个字节的含义 , 长度 , 先后顺序 , 都不允许改变 , 因为JVM靠的就是上面所说的长度 , 先后顺序等这些信息来翻译class文件 , 哪些内容是一组信息哪些符号是另外一组信息 , 清楚了这一点 , 我们再来看class文件的设计就会更加的清晰啦~ 。
class文件采用类似于C语言结构体的伪结构体来存储数据 , class文件是包含了虚拟机指令 , 符号表以及其他辅助信息这三大内容 , 还是这张表 , 包含了任意class文件的所有内容 。
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
简单介绍一下class文件结构的这张表内容:
两种数据类型:无符号数和表
无符号数属于基本数据类型(Java类中也有基本数据类型) , 以u1,u2,u4,u8这种来代表1个字节 , 2个字节,4个字节 , 8个字节的无符号数 , 可以用来描述数字 , 索引引用 , 数量值或者字符串值;表就跟Java类中的对象引用类型一样 , 对象属性可以是基本数据类型(对应U1,U2无符号数) , 也可以是其他的对象(对应其他的表),Java工程项目中参数实体通常以"_Param"结尾(class文件的表都习惯以“_info”结尾);上图中的顺序 , 就是Class文件严格要求的顺序;各个计数器主要是用来描述表里面数据个数 , 例如方法计数器的值是methods_count,代表方法表method——info里面有“methods_count”个方法;【路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码】JAVA代码千变万化 , 然而所有的内容却都归纳在了区区一张表里面?弄不懂这张表 , 誓不当程序员!!!但愿不会啪啪打脸 。
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
每个Class文件的头4个字节成为魔数(MagicNumber),它唯一的作用是确定这个文件是否为一个能被虚拟机接受的Class文件 。 值为:0xCAFEBABE(咖啡宝贝)
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
紧接魔数的4个字节是Class文件的版本号:第5-6字节是次版本号(MinorVersion) , 第7-8字节是主版本号(MajorVersion)
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
J2SE8=52(0x34hex)J2SE7=51(0x33hex)J2SE6.0=50(0x32hex)J2SE5.0=49(0x31hex)JDK1.4=48(0x30hex)JDK1.3=47(0x2Fhex)JDK1.2=46(0x2Ehex)JDK1.1=45(0x2Dhex)复制代码这是十六进制分别对应的JDK版本号 , 十六进制的34换算成十进制是52 , 对应jdk1.8 , 由于本人用的是JDK1.8所以此处是34 。 高版本的JDK能向下兼容低版本的class文件 , 但不能运行比他高版本的class文件 。