这期内容当中小编将会给大家带来有关深入浅析Java中的class文件格式,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
class文件中的fields_count和fields
fields_count描述的是当前的类中定义的字段的个数, 注意, 这里包括静态字段, 但不包括从父类继承的字段。 如果当前class文件是由一个接口生成的, 那么这里的fields_count描述的是接口中定义的字段, 我们知道, 接口中定义的字段默认都是静态的。此外要说明的是, 编译器可能会自动生成字段, 也就是说, class文件中的字段的数量可能多于源文件中定义的字段的数量。 举例来说, 编译器会为内部类增加一个字段, 这个字段是指向外围类的对象的引用。
位于fields_count下面的数据叫做fields, 可以把它看做一个数组, 数组中的每一项是一个field_info 。这个数组中一共有fields_count个field_info , 每个field_info都是对一个字段的描述。 下面我们详细讲解field_info的结构。 每个field_info的结构如下:
(1)access_flags
其中access_flags占两个字节, 描述的是字段的访问标志信息。 这里就不在详细介绍了, 下面给出一张表格(该表格来自《深入Java虚拟机》):
(2)name_index
access_flags下面的两个字节是name_index, 这是一个指向常量池的索引, 它描述的是当前字段的字段名。 这个索引指向常量池中的一个CONSTANT_Utf8_info数据项。 这个CONSTANT_Utf8_info数据项中存放的字符串就是当前字段的字段名。
(3)descriptor_index
name_index下面的两个字节叫做descriptor_index , 它同样是一个指向常量池的索引, 它描述的是当前字段的描述符。 这个索引指向常量池中的一个CONSTANT_Utf8_info数据项。 这个CONSTANT_Utf8_info数据项中存放的字符串就是当前字段的描述符。
(4)attributes_count和attributes
descriptor_index 下面是attributes_count和attributes 。 这是对当前字段所具有的属性的描述。 这里的属性和源文件中的属性不是同一个概念, 在源文件测层面中, 属性是字段的另一种叫法, 希望读者不要疑惑。读者也不要轻视class文件中的属性, 这些属性可以描述很多的信息。 我们会在后面的文章中进行介绍。
attributes_count表示这个字段有几个属性。attributes 可以看成一个数组, 数组中的每一项都是一个attribute_info , 每个attribute_info 表示一个属性, 数组中一共有attributes_count个属性。可以出现在filed_info中的属性有三种, 分别是ConstantValue, Deprecated, 和 Synthetic。 这些属性会在后面的文章中进行介绍。
下面我们以代码的形式进行解释, 源码如下:
包com.bjpowernode.test; 公开课程式设计师延伸人{ 私人电脑电脑; 公共程式设计师(电脑电脑){ this.computer=计算机; } 公共空间doWork () { computer.calculate (); } }
反编译之后,常量池中会有如下信息(这里省略了大部分无关信息):
常量池: …… …… # 5=Utf8电脑 # 6=Utf8 Lcom/詹/张/计算机; …… …… { 私人com.jg.zhang。计算机计算机; 国旗:ACC_PRIVATE …… …… }
从反编译的结果可以看的出,源文件中定义了一个计算机类型的字段的电脑,并且是私人的,然后常量池中有这个字段的字段名和描述符。其中常量池第五项的CONSTANT_Utf8_info是字段名,,第六项的CONSTANT_Utf8_info是该字段的描述符。这里有一点需要说明,在反编译Programer.class时,由于电脑是私有的,,要加——私人选项,否则的话,虽然常量池中有字段引用信息,但是不会输出字段信息,即下面这两行不会输出:
javap (- - c - v 类路径中。com.bjpowernode.test.ProgramerJava中深入浅析的类文件格式