📚《深入浅出JVM字节码》

《Java虚拟机字节码:从入门到实战》的开源版本。作者通过自己的实战经验,整合出一套适合新手的高效学习教程。归纳并提炼知识点,制定合理路线,帮助读者更快掌握核心技术。


给类添加字段

给类添加字段可调用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 日
作者: 吴就业
链接: https://github.com/wujiuye/JVMByteCodeGitBook
来源: Github Pages 开源电子书《深入浅出JVM字节码》(《Java虚拟机字节码从入门到实战》的第二版),未经作者许可,禁止转载!


📚目录