Class文件解读(四)

接上篇:http://www.javashuo.com/article/p-oibmohyh-mb.htmljava

字段表集合数组

        字段表(field_info)用于描述接口或者类中声明的变量。字段(field)包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。在java中描述一个字段能够包含的信息有:字段的做用域(public、private、protected修饰符)、是实例变量仍是类变量(static修饰符)、可变性(final)、并发可见性(volatile修饰符,是否强制从主内存读写)、能否被序列化(transient修饰符)、字段数据类型(基本类型、对象、数组)、字段名称。上述这些信息中,各个修饰符都是布尔值,要么有某个修饰符,要么没有,很适合使用标志位来表示。而字段叫什么名字、字段被定义为何数据类型,这些都是没法固定的,只能引用常量池中的常量来描述。下表描述的字段表结构。并发

              

       字段修饰符放在access_flags项目中,它与类中的access_flags是很是相似的,都是一个u2的数据类型,其中能够设置的表示位和含义以下表。spa

                

跟随access_flags标志的是两项索引值:name_index和descriptor_index。它们都是对常量池的引用,分别表明着字段的简单名称及字段和方法的描述符。如今须要解释一下“简单名称”、“描述符”以及前面出现过屡次的“全限定名”这三种特殊字符串的概念。.net

       全限定名很好理解,其实就是把类全名中的"."换成"/"而已,为了使链接的多个全限定名之间不产生混淆,在使用时最后通常会加一个";"表示全限定名结束。简单名称是指没有类型和参数修饰的方法或者字段名称。对象

        相对于全限定名和简单名称来讲,方法和字段的描述符就要复杂一些。描述符的做用是用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。根据描述符规则,基本数据类型(byte、char、double、float、int、long、short、boolean)以及表明无返回值的void类型都用一个大写字符来表示,而对象类型则用字符L加对象的全限定名来表示。blog

                                                                    描述符标识字符含义继承

标识字符 含义 标识字符 含义
B 基本类型byte J 基本类型long
C 基本类型char S 基本类型short
D 基本类型double Z 基本类型boolean
F 基本类型float V 特殊类型void
I 基本类型int L 对象类型,如Ljava/lang/Object

对于数组类型,每一维度将使用一个前置的"["字符来描述,如一个定义为"java.lang.String[][]"类型的二维数组,将被记录为:"Ljava/lang/String;",一个整型数组"int[]"将被记录为"[I"。索引

        用描述符来描述方法时,按照先参数列表,后返回值的顺序描述,参数列表按照参数的严格顺序放在一组小括号"()"以内。如方法void inc()的描述符为"()V",将方法java.lang.String toString()的描述符为"()Ljava/java/String;",方法int indexOf(char[] source,int sourceCount,char[] target,int targetOffset,int targetCount,int fromIndex)的描述符为“([CII[CII])I”。接口

        字段表都包含的固定数据项目到descriptor_index为止就结束了,不过在descriptor_index以后跟随着一个属性表集合用于存储一些额外的信息,字段均可以在属性表中描述零至多项的额外信息。对于本例中的字段n,它的属性表计数器为0,也就是没有须要额外描述的信息,可是对于本例中的m字段,它的属性表为1,结合https://my.oschina.net/u/3345762/blog/880152中常量池信息及下图能够看出,它存在一项名称为ConstantValue的属性,其值指向常量5(关于ConstantValue型属性结构会在下面篇章中阐述到,此处偏移地址Ox00000120,值为Ox0008,表示指向常量池第八个常量,查询得其值为ConstantValue,偏移地址Ox00000130,值为Ox0009,表示指向常量池中第九个常量,查询得其值为5)。

                        

       字段表集合中不会列出从超类或者父接口中继承而来的字段,但有可能列出本来Java代码之中不存在的字段,譬如在内部类中为了保持对外部类的访问性,会自动添加指向外部类实例的字段,另外,在Java语言中字段是没法重载的,两个字段的数据类型、修饰符无论是否相同,都必须使用不同的名称,可是对于字节码来说,若是两个字段的描述符不一致,那字段重名就是合法的。

下篇:http://www.javashuo.com/article/p-xdetuxcw-ky.html

相关文章
相关标签/搜索