2

我有这两个接口:

public interface Attribute<N> {

    Class<N> getAttributeType();
}

public interface FieldSubscriber<N> {

    void notifySubscriber(N value);
}

现在我有一个 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);
    ....
    ....
}

这不会编译,因为: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 回答