结构OverView(structure)
编译类(class)的整体结构很简单。不像本地编译程序,一个编译class有结构信息和从源码而来的大多数符号标记。事实上,它包含以下几部分:1)描述class的modifiers(如public、private),name,super class、interface和annotation的部分。
2)描述class中每个field的部分(section),每个section描述modifiers、name、type和annotation。
3)类中每个method和constructor描述。这里描述包括方法的modifiers、name、return type、parameter type和annotation。它也包含方法的编译代码(Java字节码指令序列形式)
源码和编译后的代码区别:
1)编译后的class仅描述单个class,而源码文件能包含多个class。举例来说,拥有内部类的源文件被编译后分成两个类文件,一个是main class和inner class。main class拥有它的inner class的引用。
2)编译后的class不会包含注释,但会包含class、field、method和code的属性(与其他elements有关联)
3)编译后的class不会包含package和import部分,所以所有type name必须是全名。另外一个结构不同在于:编译后的class包含常量池。这个池子是一个包含所有出现在class中numeric、string、type constant的数组。这些常量仅仅被定义一次,在常量池中的常量被class file的其他部分以index(索引)方式引用。ASM隐藏了常量池的相关细节。
Internal names
在很多情况下,type被限制为一个class或interface。如一个class的父类、实现接口或异常,这些type在编译后class中称为内部名称(internal name)。类的内部名称就是一个类的全称,点(.)被替换成了斜杠(/)。String的内部名称是java/lang/String
Type descriptors
internal name仅当作为class或interface使用时才能被使用。在其他情况下,如filed type,java type在编译后class中以type descriptor形式呈现。
基本类型的描述符是单个字符,如Z代表boolean,C代表char等。class type的描述符是以"L"开头+类的internal名字+分号(;)。数组的描述符号是"["开头+数组元素类型描述符。
Method descriptors
方法的描述符是一组type描述符列表(描述参数类型和返回类型)的单个字符串。一个方法描述符是"("+每个参数的type描述符+")"+返回type描述符。一旦知道type描述符如何工作,理解方法描述就很容易了。例如,(I)I描述一个方法:一个参数为int,且返回int。