2012-04-13 7 views
2

ジェネリックとマップにNパラメータを保証するために試してみてください。私はそれがサブスクリプション機能を提供しています例えばフィールド関係の異なる種類のハンドラ]しますFieldRelationsManagerクラスを、持っている今 私はこの2つのインターフェイスを持つ

public interface Attribute<N> { 

    Class<N> getAttributeType(); 
} 

public interface FieldSubscriber<N> { 

    void notifySubscriber(N value); 
} 

場所FieldSubscriberは、一部のバリューホールダーの値変更を通知するために登録することができます。 マネージャは、通知する必要のあるサブスクリプションを知るために、特定の属性のFieldSubscribersのリストを必要とします。 のでFieldRelationsManagerは、次のようになりますようにマネージャーのクライアントが同じNの属性にFieldSubscriptorを提供し、私は方法を提供しようとしていることを保証するために、

public class FieldRelationsManager { 

    private Map<Attribute<?>, List<FieldSubscriber<?>>> subscribers; 
    ..... 
    ..... 
} 

public <N> void subscribe(Attribute<N> attr, FieldSubscriber<N> subscriber){ 

    if(subscribers==null){ 
     subscribers=new HashMap<Attribute<?>, List<FieldSubscriber<?>>>(); 
    } 
    List<FieldSubscriber<N>> list=subscribers.get(attr); 
    .... 
    .... 
} 

これは次の理由でコンパイルされません。 subscribers.get(attr); リターン:

List<FieldSubscriber<?>> 

とにキャストすることはできません。そこで質問がある

List<FieldSubscriber<N>> 

、私はNパラメータは同じになることを保証するために、これをコーディングすることができ、他の方法があるのですか?

+2

Javaでジェネリックを使用すると、実行時に型情報が消去され、使用できなくなります。これを回避するためのエレガントな方法はありません。型情報が本当に必要な場合は、明示的にクライアントコードに 'Class'引数を渡す必要があります。 – jpm

答えて

2

のJavaのジェネリック情報のみをコンパイル時に使用されています。その後、プログラムが実行されると、オブジェクトのリストでJavaが動作します。

だから、何の問題もこのように

public <N> void subscribe(Attribute<N> attr, FieldSubscriber<N> subscriber) { 

せずに、あなたはコンパイラは、コンパイル時に、コード内でメソッドが必ずと呼ばれていることを確認していることを確認することができ、<N>を使用して、このようなあなたの方法を定義します両方ともN型引数。

しかし、あなたが仕事や引数はあなたが望むタイプであることを確認することができますメソッド内で一度<?>

List<FieldSubscriber<?>> list = subscribers.get(attr); 
if (list == null) { 
    list = new ArrayList<FieldSubscriber<?>>(); 
    subscribers.put(attr, list); 
} 
list.add(subscriber); 

を使用して、リストを持つメソッドの仕事、内部。

0

あなたは試みることができる:

public <N extends Iface> void subscribe(Attribute<N> attr, 
    FieldSubscriber<N> subscriber) 
{ 
    if(subscribers==null){  
    subscribers=new HashMap<Attribute<? extends Iface>, 
     List<FieldSubscriber<? extends Iface>>>();  
    }  
    List<FieldSubscriber<? extends Iface>> list=subscribers.get(attr); 
    list.add(subscriber); 
    ....  
    ....  
} 

public interface Attribute<N> { 
    Class<N> getAttributeType(); 
} 

public interface FieldSubscriber<N> { 
    void notifySubscriber(N value); 
} 

public class FieldRelationsManager { 
    private Map<Attribute<? extends Iface>, 
     List<FieldSubscriber<? extends Iface>>> subscribers; 
    ..... 
    ..... 
} 
関連する問題