给类添加字段
给类添加字段
给类添加字段可调用类访问者ClassWriter的visitField方法,该方法可添加静态字段,也可添加非静态字段。visitField方法的定义如下。
public final FieldVisitor visitField(final int access,final String name, final String descriptor,final String signature,final Object value)
visitField方法的各参数说明:
◆access:字段的访问标志,如public、final、static;
◆name:字段的名称;
◆descriptor:字段的类型描述符,如”Ljava/lang/String;”;
◆signature:字段的类型签名;
◆value:字段的初始值,此参数只用于静态字段,如接口中声明的字段或类中声明的静态常量字段,并且类型必须是基本数据类型或String类型。
如果是添加静态常量字段,且字段类型是基本数据类型或String类型,那么指定value,ASM会为该字段生成一个ConstantValue属性,同时也会为value生成一个对应类型的常量。如value的类型为int类型,则会为value生成一个CONSTANT_Integer_info常量并添加到常量池中。
比如添加一个静态常量字段,且类型为int类型,代码如下。
FieldVisitor fieldVisitor = classWriter.visitField(ACC_PUBLIC | ACC_STATIC | ACC_FINAL,"age", "I", null, 100);
比如添加一个非静态字段,类型为String,代码如下。
FieldVisitor fieldVisitor = classWriter.visitField(ACC_PRIVATE, "name", "Ljava/lang/String;", null, null);
调用visitField方法会返回一个FieldVisitor,即该字段的访问者。如果有需要,可以继续调用FieldVisitor的visitAnnotation方法给该字段添加一个注解。比如给字段添加一个lombok框架的@Getter注解,代码如下。
fieldVisitor.visitAnnotation("Llombok/Getter;", false);
现在看一个完整的例子,我们需要使用代码清单5-9的代码,然后在调用ClassWriter的visit方法之后调用我们编写的generateField方法为类添加一个字段,字段类型为String,访问标志为private,字段名为name,并且给该字段添加一个lombok框架的@Getter注解。generateField方法如代码清单5-12所示。
代码清单5-12 generateField方法
static void generateField(ClassWriter classWriter) { FieldVisitor fieldVisitor = classWriter.visitField(ACC_PRIVATE, "name", "Ljava/lang/String;", null, null); fieldVisitor.visitAnnotation("Llombok/Getter;", false); }
最终生成的AsmGenerateClass类的Java代码如下。
public class AsmGenerateClass { @Getter private String name; public AsmGenerateClass() { } }