使用 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。
我有一个项目使用枚举作为 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。