使用 ByteBuddy 在运行时定义枚举

Define Enum at Runtime using ByteBuddy

我有一个项目使用枚举作为 class 的参数,签名如下:

 public class MyClass<E extends Enum<E>> extends ExtendedClass

问题是,我不想定义枚举并为每个新枚举再次进行相同的编程。

我正在考虑 ByteBuddy 在 运行 时生成枚举。但我没有找到一种巧妙的方法来做到这一点,而且资源也不多。

编辑:

更具体地说,我的代码中有:

private enum MyEnum{
    FOO, BAR;
}

MyClass<MyEnum> obs = new MyClass<MyEnum>() 

我用ByteBuddy生成的Enum没有用;在这种情况下,它不被视为一种类型(编译错误)。

是否有一些技巧可以使用,或者仅此而已,可以在 运行 时间内完成什么?

枚举类型被编译为带有静态字段的 class,因此

enum MyEnum {
  FOO
}

编译为

class MyEnum extends java.lang.Enum<MyEnum> {
  public static final Sample FOO;
  // synthetic
  private static final Sample[] $VALUES;

  static {
    FOO = new MyEnum("FOO", 0);
    $VALUES = new MyEnum[] {FOO};
  }

  private MyEnum(String name, int ordinal) {
    super(name, ordinal);
  }

  // and other helpers
  public static MyEnum[] values() { /* $VALUES */ }
  public static MyEnum valueOf(String name) { /* $VALUES lookup */ }
}

(这就是枚举不能扩展另一个 class 只能实现接口的原因)。所以你需要生成这种 class 来模拟枚举。

您可以使用 Byte Buddy 轻松创建枚举:

Class<? extends Enum<?>> type = new ByteBuddy()
  .makeEnumeration("FOO", "BAR")
  // define methods/fields if required.
  .make()
  .load(MyClass.class.getClassLoader())
  .getLoaded();

这为您提供了一个枚举类型。您可以通过以下方式读取常量:

Enum<?> foo = Enum.valueOf(type, "FOO");
Enum<?> bar = Enum.valueOf(type, "BAR");

免责声明:但是,如果这是解决您问题的最佳方法,您的问题并没有充分描述您的用例以允许断言。

您可以在运行时从任何给定的 Collection:

检索 Enumeration
java.util.Collections.enumeration(set)

参见this SO answer