2011-11-15 16 views
2

私はこのことについて、いくつかのトピックを読んだが、それでも私は私がやりたいことを行うことができる方法を見つけ出すことはできません。Javaのジェネリック:列挙型とインタフェース

私は、特定の拡張列挙型の数を持っていますインターフェイス(HasCode)は、1つの関数code()を宣言し、このenumのintコードを返します。すべての拡張エニュラムは、コンストラクタ(等)への専用のint変数とパラメータを持っています。

私は、パラメータとしてenumクラスを受け入れ、その列挙値の名前とそれらの列挙値のint値のハッシュテーブルを返す関数を望みます。ここで

は私の列挙型の例である:

public enum InvoiceStatuses implements HasCode<InvoiceStatuses> { 
    NONE(0), REQUESTED(10), RECEIVED(20), APPROVED(30), PAID(40), ERROR(-100); 
    private int code; 
    private InvoiceStatuses(int a) { 
     code = a; 
    } 
    public int code() { 
     return code; 
    } 
    public static InvoiceStatuses invoiceStatusByCode(int aCode) { 
     switch (aCode) { 
     case 0: 
      return NONE; 
     case 10: 
      return REQUESTED; 
     case 20: 
      return RECEIVED; 
     case 30: 
      return APPROVED; 
     case 40: 
      return PAID; 
     } 
     return ERROR; 
    } 
    public int compare(InvoiceStatuses anotherLevel) { 
     if (code > anotherLevel.code()) { 
      return 1; 
     } else if (code < anotherLevel.code()) { 
      return -1; 
     } 
     return 0; 
    } 
    @Override 
    public InvoiceStatuses[] enumValues() { 
     return InvoiceStatuses.values(); 
    } 
} 

HasCode:

public interface HasCode <T extends Enum<?>>{ 
    public int code(); 
    public T[] enumValues(); 
} 

そして、ここでその魔法の機能を持つクラスである(その列挙型の値に対して反復)

import java.util.Hashtable; 
import java.util.LinkedList; 
public class SelectFromEnum&lt;T extends Enum<?>> { 
    public SelectFromEnum() {} 
    public Hashtable<String, String> createSelect(HasCode<T> anEnum) throws Exception{ 
     if (! (anEnum instanceof Enum)) { 
      throw new Exception ("I only accept enums..."); 
     } 
     T[] values = anEnum.enumValues(); 
     for (T value : values) { 
      System.out.println(value.name() + " __ " + ((HasCode)value).code()); 
     } 
     return null; 
    } 
} 

私がこれについて気に入らないもの:

1)具体的なenumメンバをパラメータとしてcreateSelect関数に渡す必要があります。私は(enum).classを渡したいと思います。

2)私はそれが与えられたインタフェースを拡張列挙型であることを指定するcreateSelectのパラメータをしたいと思いますが、私は非常にそれを行う方法を見つけ出すことはできません。

アップデート:私はSelectFromEnum次の方法(下記参照)を変更し、そして今value.name()がコンパイルされませんインゴ・ケーゲルさんのコメントに従い

...

import java.util.Hashtable; 
import java.util.LinkedList; 

public class SelectFromEnum<C extends HasCode> { 
    public SelectFromEnum() { 
    } 
    public Hashtable&lt;String, String> createSelect(Class<C> anEnum) throws Exception { 
     if (!anEnum.isEnum()) { 
      throw new Exception("I only accept enums..."); 
     } 
     C[] values = anEnum.getEnumConstants(); 
     for (C value : values) { 
      System.out.println(value.name() + " __ " + value.code()); 
     } 
     return null; 
    } 
} 

私が追加することができますname()HasCodeインターフェイスに追加しましたが、valueがenumメンバーであることをコンパイラに説得する方法はありますか?

答えて

7

enumのインスタンスを使用する必要はありません。クラスを渡してClass#isEnumClass#getEnumConstants()を使用してください。

編集

あなたはEnumClass#getEnumConstants()によって返されたオブジェクトにキャストすることができますし、あなたのコードは次のようになります。あなたは、単に、HasCodeに型パラメータを使用している理由

public LinkedList createSelectFrom(Class anEnum) throws Exception { 
    if (!anEnum.isEnum()) { 
     throw new Exception("I only accept enums..."); 
    } 
    Object[] values = anEnum.getEnumConstants(); 
    for (Object value : values) { 
     System.out.println(((Enum)value).name() + " __ " + ((HasCode) value).code()); 
    } 
} 
+0

ありがとうございました。しかし、value.name()はコンパイルされません。トピックを更新して変更を反映し、それに関する質問を追加しました。 – Ibolit

+1

@Ibolit私の編集を参照してください –

1

わかりません使用する列挙型のインターフェイスを実装します。私はあなたが実装を列挙型に制限する方法としてそれを使用しようとしていると思われますが、それは必要ではありません。インターフェースを実装するものは気にしないでください。

は、あなたはそれがあなたにとって重要ならば列挙型は、SetEnumの値になることを保証している別の方法

createSelect(EnumSet.allOf(InvoiceStatus.class)); 

public Hashtable createSelect(EnumSet<? extends HasCode> enums) { 
    for (HasCode c : enums) { 
     c.code(); 
    } 
} 

それを試してみてください。また、はるかに理解しやすく、enumのインスタンスを直接必要としません。

+0

V [] values = anEnum.getEnumConstants(); - "型の不一致:Enum []をV [] [ – Ibolit

+0

]に変換できません@Ibolit少し異なるアプローチを試してください – ptomli

関連する問題