2011-12-11 18 views
12

のは、私はそうのように、その形式の基本的な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; 
    } 
} 

を..新しいアプリケーションの周りに新しく作成されたenum SomeEnumを渡してください。どのように私はこれのような何かを達成するか?それは可能ですか?

答えて

14

あなたがしようとしていることは全く意味がありません。 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は、いくつかのCollectionに保存されているか、そうでなければ、あなたのプログラムで使用することができ、新たにインスタンス化さSalutationオブジェクト、に解析することができます。私の例では、Salutationの作成をprivateコンストラクタにすることで制作を制限しました。この場合、インスタンスを取得する唯一の方法は、XMLをとるファクトリメソッドを呼び出すことです。私はこれがあなたが探している行動を達成すると信じています。

+0

は理にかなっています。私の階層にはあまりにも多くの人がいます(ちょっとばかりではなく、ほんの少しです)、私はそれらを排除したいと考えていたので、具体的にenumについて尋ねました。 –

+0

@Chris - コード生成に関する質問や実行時の作成についてお待ちしていますか? –

+0

実際は実行時にそれらを作成することです。それは違うと思います。 –

6

実はそれが動的に列挙型のインスタンスを作成することが可能ですが、それは総ハックですが、私は全くそれに助言しません - 多分あなたはenumの性質を誤解している、それはのコンパイル時の機能です実行時にインスタンスを追加/削除することは想定されていません。

とにかく、enumインスタンスを動的に作成するためのハックに興味がある場合は、articleをご覧ください。

0

オスカー・ロペスと同意する。ここで私がやったのは、一種のハックです。

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 
0

ダイナミック列挙型は、あなたの問題への答えです:

public abstract class DEnum<E extends DEnum<E>> implements Comparable<E>, Serializable { 

このクラスあり標準のEnuに似た署名mクラス。具体的な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); 

すべてのアイテムを取得する型付けされたゲッターがあります:

YesNo[] items = yes.getItems(); 
assert (items.length == 2); 

それはすることができます(データベースまたはファイルから)実行時に動的にメンバを追加します。

YesNo maybe = getOrCreateIfNotExists(YesNo.class, "MAYBE"); 
items = yes.getItems(); 
assert (items.length == 3); 
01静的メンバと同じ動作をし

YesNo unknown = YesNo.get(YesNo.class, "MAYBE"); 
assert (unknown == maybe); 
+0

'DEnum'の実装へのリンクを含めるか、ここに投稿してください –