class字节码文件

xiaoxiao2021-02-28  58

写在前面的话

class文件结构可以说是一套规范,不一定是Java编译器编译出来的版本,它用来描述一个文件中对应的字段,类,常量池,继承关系等等。值得一提的是这个文件是完全紧凑型的。从第一个字节到最后一个字节,表达的意思按照约定好的严格规范。由于这种字节码可以运行在jvm上实现跨平台的亮点。所以不只是Java语言编译器可以编译成这种文件。class文件是学习jvm中比较重要的一环。我尽量用案例来分析一个class文件的解析。还是少一些理论性的东西.

案例源码

package structureclass.demo; public class TestClass{ private int m; public int inc(){ return m+1; } }

class字节码(winhex截图)

字节码部分构成

字节数与类型名称数量4个magic(魔数)12个minor_version(次版本号)12个major_version(主版本号)12个constant_pool_count(常量池数量,从1开始)1cp_infoconstant_pool(常量池)constant_pool_count - 12个constant_pool_count(常量池数量,从1开始)12个access_flags(访问标志)12个this_class(类索引)12个super_class(父类索引)12个interfaces_count(接口计数器)12个interfaces(接口描述)interfaces_count2个fields_count(字段表集合count)1field_infofields(字段表集合)fields_count2个methods_count(方法表集合count)1method_infomethods(方法表集合)methods_count2个attributes_count(属性表集合count)1attribute_infoattributes(属性表集合)attributes_count

class字节码文件是严格按照这个顺序占位排列的 其中_info后缀叫做为表,我们把它理解成一个数据结构即可.

magic魔数

对应位置:0+4 如图所示,标识这个文件是一个class文件,这个是严格约束的。必须是这个文件才会被识别。可以理解为后缀与魔数的唯一绑定关系。对应结果CAFE BABE

minor_version&&major_version(次版本号和主版本号)

对应位置:0+4+4 虚拟机会向下兼容其版本号,对于高于其对应版本号的文件,直接拒绝,无论格式是否正确。对应结果:JDK1.7.0。此阶段不做过多研究,安装好jdk,随意编译一下即可知道对应的版本号

constant_pool_count(常量池数量)

对应位置:0+4+4+2 constant_pool_count从1开始,所以表示的数要计算结果以后-1, 0表示不引用任何常量 16进制33等于 3*16^0+1*16^1 = 19 -1 = 18

javap -verbose 输出:

λ javap -verbose TestClass.class Classfile /E:/jvmana/TestClass.class Last modified 2018-5-18; size 295 bytes MD5 checksum 4ee039bbc694ca6a1383cb5bebb97d19 Compiled from "TestClass.java" public class structureclass.demo.TestClass SourceFile: "TestClass.java" minor version: 0 major version: 51 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #4.#15 // java/lang/Object."<init>":()V #2 = Fieldref #3.#16 // structureclass/demo/TestClass.m:I #3 = Class #17 // structureclass/demo/TestClass #4 = Class #18 // java/lang/Object #5 = Utf8 m #6 = Utf8 I #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 inc #12 = Utf8 ()I #13 = Utf8 SourceFile #14 = Utf8 TestClass.java #15 = NameAndType #7:#8 // "<init>":()V #16 = NameAndType #5:#6 // m:I #17 = Utf8 structureclass/demo/TestClass #18 = Utf8 java/lang/Object { public structureclass.demo.TestClass(); flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 3: 0 public int inc(); flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: getfield #2 // Field m:I 4: iconst_1 5: iadd 6: ireturn LineNumberTable: line 8: 0 }

我们可以看到正好是18项常量。与我们的计算结果一致。

那么,我们继续往下看

constant_pool(静态常量池)

未完待续

转载请注明原文地址: https://www.6miu.com/read-2627980.html

最新回复(0)