深入理解Android:Java虚拟机ART
上QQ阅读APP看书,第一时间看更新

2.2.2 信息描述规则

根据Java虚拟机规范,如何用字符串来描述成员变量、成员函数是有讲究的,这些规则主要集中在数据类型,成员变量和成员函数的描述三个方面,包括:

·数据类型(比如原始数据类型,引用类型)的描述规则。

·成员变量的描述规则,规范里称作Field Descriptor

·成员函数的描述规则,规范里称作Method Descriptor。

2.2.2.1 数据类型描述规则

先来看数据类型描述规则,它讲述的是数据类型如何用对应的字符串来描述:

·原始数据类型对应的字符串描述为"B""C""D""F""I""J""S""Z",它们分别对应的Java类型为byte、char、double、float、int、long、short、boolean。

·引用数据类型的格式为"LClassName;"。此处的ClassName为对应类的全路径名,比如上例中的"Ljava/lang/String;"。全路径名的“.”号由“/”替代,并且最后必须带分号。

·数组也是一种引用类型,数组用"[其他类型的描述名"来表示,比如一个int数组的描述为"[I",一个字符串数组的描述为"[Ljava/lang/String;",一个二维int数组的描述为"[[I"。

了解完数据类型描述规则后,我们接着看类的成员变量描述规则,也就是Field Descriptor。

2.2.2.2 成员变量描述规则

相当容易的事情是,成员变量(Field Descriptor)的类型就是前面所说的数据类型。为了方便读者以后自行阅读规范,笔者此处照搬规范里对Field Descriptor的定义,它采用了一种特殊的语法来描述。

[Field Descriptor描述规则]

#号后是笔者加的注释内容。注意,为了节省篇幅,此处和规范略有不同
FieldDescriptor:   #定义FieldDescriptor的描述规则
FieldType          #FieldDescriptor只包含FieldType一种信息
FieldType:         #FieldType又包含什么信息呢?可由下面三种信息组成。“|”表示或
BaseType | ObjectType | ArrayType
BaseType:          #原始数据类型,我们在上一节已经见过了,它包括:
B | C| D| F| I | J | S | Z
ObjectType:        #引用类型
L ClassName ;
ArrayType:         #数组类型,由"["加ComponentTpe构成。
[ ComponentType:      # ComponentType是一个新东西
ComponentType         :#定义ComponentType,它又是由上面定义的FieldType构成
FieldType

规范中使用的这种语法非常简洁易懂,以后我们尽可能使用它。接下来是成员函数类型的描述规则了。

2.2.2.3 成员函数描述规则

和成员变量略有不同的是,一个成员函数(Method Descriptor)的描述需要包含返回值及参数的数据类型。

[成员函数类型描述规则]

#函数描述包括两个部分,括号内的是参数的数据类型描述。括号内的*号表示可有0到多个
MethodDescriptor:     # ParamterDescriptor。紧接右括号的是返回值类型描述
( ParameterDescriptor* ) ReturnDescriptor
ParameterDescriptor:  #参数类型描述就是前面介绍过的FieldType
FieldType
ReturnDescriptor:     #返回值数据类型描述。如果返回值为void,则用VoidDescriptor描述
FieldType | VoidDescriptor
VoidDescriptor:       #"v"代表void
V

举个例子,比如System.out.print(String str)函数,它的Method Descriptor将是:

(Ljava/lang/String;)V。

注意 Method Descriptor不包括函数名。这么做的目的其实也是为了节省空间。因为很多函数可能名字不同,但是它们的MethodDescriptor却一样。