上篇先容了字节码文件的布局和其常量池阐明。紧接其后呢,我们要去相识字段表的观念和构成布局。接着上篇里的字节码的常量池往后阐明。
access_flags
会见符号信息包罗该class文件是类照旧接口,是否界说成public,是否是abstract,假如是类,是否被申明为final。access_flags 的取值范畴和相应寄义见下表。
劳务调派打点系统 a/lang/String; 暗示该字段是String范例" class="aligncenter size-full wp-image-30506" title="Snipaste_2018-11-19_12-53-53" src="/uploads/allimg/c181120/1542ALE463Z-15T4.png" />
我们的字节码里该位置的16进制暗示是0×0021。0×0021=0×0001 ^ 0×0020。即代表该类的会见修饰是public的。ACC_SUPER这里不做先容,看看JVM类型对他的描写,相识即可。
ACC_SUPER 符号用于确定该 Class 文件内里的 invokespecial 指令利用的是哪一种执行语义。今朝 Java 虚拟机的编译器都该当配置这个符号。ACC_SUPER 标志是为了向后兼容旧编译器编译的 Class 文件而存在的,在 JDK1.0.2 版本以前的编译器发生的 Class 文件中,access_flag 内里没有 ACC_SUPER 符号。同时,JDK1.0.2 前的 Java 虚拟机会到 ACC_SUPER 标志会自动忽略它。
this_class_name
类索引,this_class 的值必需是对 constant_pool 表中项目标一个有效索引值。constant_pool 表在这个索引处的项必需为 CONSTANT_Class_info 范例常量,暗示这个 Class 文件所界说的类或接口。
在我的字节码文件中,该16进制值为0×0005=5。通过常量池信息,最终他指向的是一个utf-8字符串,com/shengsiyuan/jvm/bytecode/MyTest2。即类的全限命名。
#5 = Class #38 // com/shengsiyuan/jvm/bytecode/MyTest2 #38 = Utf8 com/shengsiyuan/jvm/bytecode/MyTest2
super_class_name
父类索引,昆山软件开发,对付类来说,super_class 的值必需为 0 可能是对 constant_pool 表中项目标一个有效索引值。
在字节码文件中,父类索引为0x000A=10。即父类是 java/lang/Object。
#10 = Class #43 // java/lang/Object #43 = Utf8 java/lang/Object
interfaces_count
接口计数器,interfaces_count 的值暗示当前类或接口的直接父接口数量。
我们的代码没有实现任何接口,所以该项值为0,即0×0000。
interfaces[]
接口表,interfaces[]数组中的每个成员的值必需是一个对 constant_pool 表中项目标一个有效索引值,它的长度为 interfaces_count。
我们代码没有接口,所以我们的字节码文件里没有这项了。所以 interfaces_count 后头就直接是字段计数器和字段表。
fields_count
字段计数器,fields_count 的值暗示当前 Class 文件 fields[]数组的成员个数。也就是当前类的类字段和实例字段的个数。
我们源代码里界说了3个字段,1个类字段,2个实例字段。所以fields_count为3。查察对应字节码文件的16进制暗示0×0003=3。
fields[]
字段表用于描写类和接口中声明的变量。这里的字段包括了类级别变量以及实例变量,可是不包罗要领内部声明的局部变量。
field_info布局名目如下:
field_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attribute_info attributes[attributes_count]; }
access_flags 项的值是用于界说字段被会见权限和基本属性的掩码符号。access_flags 的取值范畴和相应寄义见如下表:
劳务调派打点系统 a/lang/String; 暗示该字段是String范例" class="aligncenter size-full wp-image-30507" title="Snipaste_2018-11-19_12-57-24" src="/uploads/allimg/c181120/1542ALE5G10-22M4.png" />
看在我字节码中的16进制暗示,0×0000=0。0代表没有修饰符的意思。看我们的源码:String str = “Welcome”;,即默认修饰符。
在字节码里是0x000B=11。常量池11处:
#11 = Utf8 str
暗示字段的名称为“str”。
字节码中,0x000C=12。看常量池:
#12 = Utf8 Ljava/lang/String;
暗示该字段是String范例。
在JVM类型中,每个变量/字段都有描写信息,描写信息主要浸染是描写字段的数据范例、要领的参数列表(包罗数量,范例与顺序)与返回值。按照描写符法则,根基数据范例和代表无返回值的void范例都用一个大写字符来暗示,工具范例则利用字符L加工具的全限命名称来暗示。为了压缩字节码文件的体积,对付根基数据范例,JVM都只利用一个大写字母暗示,如下所示:B-byte、C-char、D-double、F-float、I-int、J-long、S-short、Z-boolean、V-void、L-工具范例,如Ljava/lang/String。
对付数组范例来说,劳务派遣管理系统,每一个纬度使一个前置的[暗示,如int[]被记录为[I,String[][]被记录为[[Ljava/lang/String;。
在字节码里,0x0000=0。即该字段没有附加属性。
attributes 表的每一个成员的值必需是 attribute布局,一个字段可以有任意个关联属性。
因为该字段没有附加属性,所以这项数据没有。