2

私はこの2つのインターフェースを持っています:

public interface Attribute<N> {

    Class<N> getAttributeType();
}

public interface FieldSubscriber<N> {

    void notifySubscriber(N value);
}

これで、さまざまな種類の Fields リレーションを処理する FieldRelationsManager クラスができました。たとえば、FieldSubscriber がサブスクライブして、値ホルダーの値の変更を通知できるサブスクリプション機能を提供します。したがって、マネージャーは、通知する必要があるサブスクリプションを知るために、特定の属性の FieldSubscribers のリストを必要とします。したがって、FieldRelationsManager は次のようになります。

public class FieldRelationsManager {

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

マネージャーのクライアントが同じ N の属性に FieldSubscriptor を提供することを保証するために、次のようなメソッドを提供しようとしています。

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);
    ....
    ....
}

これは次の理由でコンパイルされません。戻り値:

 List<FieldSubscriber<?>> 

以下にキャストすることはできません。

List<FieldSubscriber<N>>

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

4

2 に答える 2

2

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

したがって、<N>問題なくを使用して、このようにメソッドを定義します

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

Nこのようにして、コンパイラはコンパイル時に、コード内でメソッドが常に両方の型引数で呼び出されることを確認できます。

ただし、メソッド内では、リストを使用して作業します<?>

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

メソッド内で作業を行い、引数が目的の型であることを確認できます。

于 2012-04-13T18:01:07.387 に答える
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;   
  .....   
  .....   
} 
于 2012-04-13T17:58:45.797 に答える