动态生成枚举

时间:2011-12-11 20:30:15

标签: java enums runtime

假设我有一个格式为基本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。我怎么能达到这样的目的?它可行吗?

4 个答案:

答案 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);