接上篇:https://my.oschina.net/u/3345762/blog/889512
字段表集合
字段表(field_info)用于描述接口或者类中声明的变量。字段(field)包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。在java中描述一个字段可以包含的信息有:字段的作用域(public、private、protected修饰符)、是实例变量还是类变量(static修饰符)、可变性(final)、并发可见性(volatile修饰符,是否强制从主内存读写)、可否被序列化(transient修饰符)、字段数据类型(基本类型、对象、数组)、字段名称。上述这些信息中,各个修饰符都是布尔值,要么有某个修饰符,要么没有,很适合使用标志位来表示。而字段叫什么名字、字段被定义为什么数据类型,这些都是无法固定的,只能引用常量池中的常量来描述。下表描述的字段表结构。
字段修饰符放在access_flags项目中,它与类中的access_flags是非常类似的,都是一个u2的数据类型,其中可以设置的表示位和含义如下表。
跟随access_flags标志的是两项索引值:name_index和descriptor_index。它们都是对常量池的引用,分别代表着字段的简单名称及字段和方法的描述符。现在需要解释一下“简单名称”、“描述符”以及前面出现过多次的“全限定名”这三种特殊字符串的概念。
全限定名很好理解,其实就是把类全名中的"."换成"/"而已,为了使连接的多个全限定名之间不产生混淆,在使用时最后一般会加一个";"表示全限定名结束。简单名称是指没有类型和参数修饰的方法或者字段名称。
相对于全限定名和简单名称来说,方法和字段的描述符就要复杂一些。描述符的作用是用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。根据描述符规则,基本数据类型(byte、char、double、float、int、long、short、boolean)以及代表无返回值的void类型都用一个大写字符来表示,而对象类型则用字符L加对象的全限定名来表示。
描述符标识字符含义
| 标识字符 | 含义 | 标识字符 | 含义 |
| 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语言中字段是无法重载的,两个字段的数据类型、修饰符不管是否相同,都必须使用不一样的名称,但是对于字节码来讲,如果两个字段的描述符不一致,那字段重名就是合法的。
下篇:https://my.oschina.net/u/3345762/blog/898561
转载于:https://my.oschina.net/u/3345762/blog/894106