1

状況:フィールドは、観察したいモデルのプロパティである可能性があります (PropertyChangeListener に似たもの)。フィールドは Enum として定義されます。電話したい

someModel.getField(Field f).addObserver(FieldObserver<Something> observer)

オブザーバーの型 (「何か」) はフィールドに依存するため、型安全性を強制したいと考えています。たとえばField.FIRST_NAMEFieldObserver< String>.

最初の (実用的な) アプローチ: Field を enum ではなく public static final フィールドを持つジェネリック クラスとして定義することで、すでに到達できました。したがって、次のように型の安全性を強制するために使用できる Field があります。

public <E> Observable<E> getField(Field<? extends E> f)

のメソッドを使用Observable<E>:void addObserver(FieldObserver<? super E> observer)

次の行はコンパイル時エラーを引き起こします。これは私が望むものです:

someModel.getField(Field.some_STRING_field).addObserver(INTEGERObserver)

2 番目の (まだ機能していない) アプローチ: enum クラスで同じ動作を実装しようとしています。私のアプローチの1つは次のとおりです。

public enum Field{
 FIRST_NAME("firstName") {
        @Override
        public Observable<String> getObservable() {
            return new Observable<String>();
        }
    },...

    //every Field must implement:
    public abstract FieldObservable.Observable<?> getObservable();`
 } 

 //getField(Field f) of the Model-class:
 public Observable<?> getField(Field f){
    return f.getObservable();
 }

任意のタイプ (これも正しいタイプ) の FieldObserver を追加しようとすると、次のようなコンパイル時エラーが発生します。

Observable の addObserver (enumer.FieldObserver< capture< ?>>) は (enumer.FieldObserver< java.lang.String>) には適用できません

誰かが列挙型アプローチを機能させる方法を教えてもらえますか? また、誰かがアプローチについてより良い解決策や懸念を持っている場合は、それを聞いて感謝します.

4

1 に答える 1

4

残念ながら、enums をジェネリックにすることはできません。これは、enumが を拡張する通常のクラスであるためですEnum。つまり、その定義は次のようになります。

class MyEnum<E extends Enum<E>> extends Enum<E extends Enum> {}

そのため、アプリケーション プログラマは、このクラスに汎用パラメータを追加することはできません。

次の回避策を提案できます。

  1. メソッドをジェネリックにします。enumとしてレベルで定義しますpublic <T> getField(Class<T> type)。列挙型メンバーごとにこのメソッドをオーバーライドします。次に、メソッドの任意の呼び出しで型を指定できます。
  2. このタスクには enum を使用しないでください。public static メンバーと private コンストラクターを持つ通常のクラスを作成します。列挙型のような動作が必要な場合は、独自の静的values()およびを実装しますvalueOf()
于 2014-01-26T15:20:19.480 に答える