java - 如何使用 Byte Buddy 创建一个枚举,其中包含由每个枚举常量初始化的字段?

标签 java byte-buddy

我想使用 Byte Buddy 生成一个包含字段的枚举,其中每个枚举常量将不同的参数传递给构造函数。

public enum MyEnum {
    private final String blah;
    A("foo")
    B("bar");

    private MyEnum(String blah) {
        this.blah = blah;
    }
}

我试过这个:

new ByteBuddy()
    .makeEnumeration("A", "B")
    .name("com.foo.MyEnum")
    .defineField("blah", String.class, Modifier.FINAL | Modifier.PRIVATE)
    .defineConstructor(Visibility.PRIVATE)
    .withParameters(String.class)
    .intercept(
        FieldAccessor.ofField("blah").setsArgumentAt(0)
    )
    .make()

生成这个(反编译)。这两个具有相同签名的构造函数有点奇怪,但无论如何。

public enum MyEnum {
    private final String blah;
    A,
    B;

    private MyEnum() {
    }

    private MyEnum() {
        this.blah = var1;
    }
}

我看不出有什么方法可以将每个枚举常量与一组构造函数参数相关联。 makeEnumeration 方法只有两个签名,它们都接受一个字符串集合。

字节好友可以做到这一点吗?

最佳答案

Byte Buddy 目前不允许您生成这种确切的字节代码模式,但您可以通过拦截方法并检查拦截方法中的当前实例名称并相应地返回值来实现相同的目的。

如果你想定义一个字段,你也可以拦截枚举构造函数并替换Byte Buddy的原始实现。您定义的构造函数无效,因为 Enum 类不提供默认构造函数。而是应用以下内容:

builder = builder.constructor(any()).intercept(SuperMethodCall.INSTANCE.andThen(...))

您可以在其中应用任何拦截器实现。例如,您可以应用 MethodDelegation,例如:

class FieldSetter {
  static void fields(@Argument(0) String name) {
    // implement logic
  }
}

枚举定义了一个构造函数,枚举名称作为第一个参数,序数整数作为第二个参数。您还可以使用 Advice 并使用 visit 注册装饰。

关于java - 如何使用 Byte Buddy 创建一个枚举,其中包含由每个枚举常量初始化的字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57629114/

相关文章:

java - Bytebuddy拦截异常抛出

java - 如何使用 Bytebuddy 拦截字段访问(无需 getter/setter)

java - Web应用程序请求过滤器

java - PhraseQuery 在 Apache lucene 7.2.1 中不起作用

java - 当 var 包含 ".0"时如何将 String 转换为 BigInteger

java - 在 ByteBuddy 中从头开始创建类构造函数

java - 流中的条件过滤器

java - 从jar中提取exe后出现错误

java - 从 Byte Buddy 0.7.7 迁移到 1.0.2 时遇到问题

java - 使用不带 -javaagent 参数的 ByteBuddy Java 代理