给类添加字段
给类添加字段可调用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.4《创建类并创建方法》中的案例代码,在调用ClassWriter实例的visit方法之后,调用我们编写的generateField方法,为类添加一个字段,字段类型为String,访问标志为private,字段名为name,并且给该字段添加一个lombok框架的@Getter注解。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() {
}
}
发布于:2021 年 10 月 10 日
作者: 吴就业
GitHub链接:https://github.com/wujiuye/JVMByteCodeGitBook
链接:https://www.wujiuye.com/ebook/JVMByteCodeGitBook/chapter/chapter05_05.md
来源: Github Pages 开源电子书《深入浅出JVM字节码》(《Java虚拟机字节码从入门到实战》的第二版),未经作者许可,禁止转载!