Copyright c 2007, Eric Bruneton
2. 类
本章主要介绍如何使用ASM Core API进行类的生成和转换。
2.1 结构
2.1.1 概览
一个已编译的Java类文件的结构是十分简单的。和本地编译型程序不同,已编译的Java类文件包含了结构化的信息和源代码中的几乎所有符号。
一个已编译的Java类文件中包括一下内容:
>一个描述本类的修饰符(如public、private)、类名、超类、接口、注解的节。
>本类所声明的所有字段的节(一个字段一个节),节中包含了字段的修饰符、名称、类型、注解。
>本类所声明的所有方法(包括构造器)的节(一个方法一个节),节中包含了方法的修饰符、名字、返回值类型、参数类型、注解,以及该方法的字节码指令序列。
虽然Java字节码文件和源文件有很多相似之处,但是它们还是有区别的:
>一个已编译的Java类文件中只包含一个类的信息,而源文件中却可以声明多个类。
>已编译的Java类文件中不包含注释信息(除了注解)。
>已编译的Java类文件中不包含包信息,所以所有的成员必须使用全路径。
>已编译的类中包含一个常量池,该常量池是一个持有本类所有数字、字符串、对象常量的数组。
2.1.2 内部名字
在很多情况下,一个类型只能是类或接口。例如一个类的超类、一个类所实现的接口、方法抛出的异常的类型等,不可能事基本类型或数组类型。这些类型在字节码文件中使用内部名字(完全路径名)表示。比如String类型的内部名字是java/lang/String。
2.1.3 类型描述符
内部名字仅能用于类或接口。其他情况下,Java类型在字节码文件中是使用类型描述符来进行表示的。
以下是一些Java类型的描述符对照表:
Java类型 类型描述符
boolean Z
char C
byte B
short S
int I
float F
long J
double D
Object Ljava/lang/Object;
int[] [I
Object[][] [[Ljava/lang/Object;
可以看到,类类型的描述符以字母L打头,后跟类的内部名字,最后以分号;结尾。比如String的描述符为:Ljava/lang/String;
类类型的数组为上方括号[打头,后跟类类型的描述符,最后以分号;结尾。
2.1.4 方法描述符
方法描述符是一个由方法的参数类型描述符和返回值类型描述符组成的描述符列表。
以下是一些方法的方法描述符示例(一看差不多就明白了):
方法声明 方法描述符
void m(int i, float f) (IF)V
int m(Object o) (Ljava/lang/Object;)I
int[] m(int i, String s) (ILjava/lang/String;)[I
Object m(int[] i) ([I)Ljava/lang/Object;