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

How can I create an enum with fields initialized by each enum constant using 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 class 不提供默认构造函数。而是应用以下内容:

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

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

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

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

注册装饰