假设我有一个格式为基本XML的文件,如下所示:
<?xml version="1.0"?>
<enum-set>
<enum>
<name>SomeEnum</name>
<values>
<value>
<name>SOMEVALUE</name>
<displayText>This is some value</displayText>
</value>
... more values ...
</values>
</enum>
... more enums ...
</enum-set>
我希望在运行时将SomeEnum
变成这样的东西:
public enum SomeEnum implements HasDisplayText {
SOMEVALUE("This is some value"),
... more values ...;
private String displayText;
SomeEnum(String displayText) {
this.displayText = displayText;
}
@Override
public String getDisplayText() {
return displayText;
}
}
...然后在我的应用程序周围传递新创建的枚举SomeEnum
。我怎么能达到这样的目的?它可行吗?
答案 0 :(得分:17)
你要做的事情并没有多大意义。 Enums实际上只是为了编译时间,因为它们代表一组固定的常量。在运行时,动态生成的枚举的含义是什么 - 这与普通对象有何不同?例如:
public class Salutation implements HasDisplayText {
private String displayText;
private Salutation(String displayText) {
this.displayText = displayText;
}
@Override
public String getDisplayText() {
return displayText;
}
public static Collection<Salutation> loadSalutations(String xml) {
//parse, instantiate, and return Salutations
}
}
您的XML可以解析为新实例化的Salutation
对象,这些对象可以存储在某些Collection
中,也可以由您的程序使用。请注意,在我的示例中,我通过给它Salutation
构造函数来限制private
的创建 - 在这种情况下,检索实例的唯一方法是调用带有XML的工厂方法。我相信这可以实现你正在寻找的行为。
答案 1 :(得分:7)
实际上 可以动态地创建枚举实例,但这完全是黑客攻击,我根本不会建议 - 也许你误解了enum
的性质,它是该语言的编译时功能,您不应该在运行时添加/删除它的实例。
无论如何,如果您对动态创建枚举实例的hack感兴趣,请查看此article。
答案 2 :(得分:1)
同意奥斯卡·洛佩兹。这就是我所做的,一种破解。
public static enum Setter {
DYNAMIC_ENUM_EXAMPLE {
@Override
public String setGetValue(String yourValue) {
return "prefix " + yourValue + " postfix";
}
};
public abstract String setGetValue(String value);
}
你可以得到这样的价值:
Setter.DYNAMIC_ENUM_EXAMPLE.setGetValue("namaste")
输出:
prefix namaste postfix
答案 3 :(得分:0)
动态枚举是您问题的答案:
public abstract class DEnum<E extends DEnum<E>> implements Comparable<E>, Serializable {
此类具有类似于标准Enum类的签名。它有一个受保护的构造函数,允许在具体的Enum类中创建实例。例如:
public class YesNo extends DEnum<YesNo> {
public final static YesNo YES = new YesNo();
public final static YesNo NO = new YesNo();
DEnum类通过内省知道成员的名字:
String name = YesNo.YES.getName();
YesNo yes = YesNo.get(YesNo.class, name);
assert (yes == YesNo.YES);
有一个类型化的getter可以检索所有项目:
YesNo[] items = yes.getItems();
assert (items.length == 2);
它允许在运行时使用(来自数据库或文件)动态添加成员:
YesNo maybe = getOrCreateIfNotExists(YesNo.class, "MAYBE");
items = yes.getItems();
assert (items.length == 3);
与静态成员具有相同的行为:
YesNo unknown = YesNo.get(YesNo.class, "MAYBE");
assert (unknown == maybe);