Java 尝试使用泛型确保映射中的N参数

Java 尝试使用泛型确保映射中的N参数,java,generics,Java,Generics,我有两个接口: public interface Attribute<N> { Class<N> getAttributeType(); } public interface FieldSubscriber<N> { void notifySubscriber(N value); } 公共接口属性{ 类getAttributeType(); } 公共接口用户{ 无效(N值); } 现在我有了一个FieldRelationsManage

我有两个接口:

public interface Attribute<N> {

    Class<N> getAttributeType();
}

public interface FieldSubscriber<N> {

    void notifySubscriber(N value);
}
公共接口属性{
类getAttributeType();
}
公共接口用户{
无效(N值);
}
现在我有了一个FieldRelationsManager类,该类将处理不同类型的字段关系,例如,它将提供一个订阅功能,其中FieldSubscriber可以订阅以通知某个值持有者的值更改。 因此,管理器需要一个给定属性的FieldSubscriber列表,以便知道它必须通知哪些子描述。 因此FieldRelationsManager看起来像:

public class FieldRelationsManager {

    private Map<Attribute<?>, List<FieldSubscriber<?>>> subscribers;
    .....
    .....
}
公共类FieldRelationsManager{
私人地图>>订户;
.....
.....
}
为了确保manager的客户端为同一个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);
    ....
    ....
}
public void subscribe(属性attr,FieldSubscriber){
if(订阅服务器==null){
订阅者=新HashMap>>();
}
List=subscribers.get(attr);
....
....
}
这将不会编译,因为: 订阅服务器.get(attr); 返回:

 List<FieldSubscriber<?>> 
List您可以尝试:

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;   
  .....   
  .....   
} 
public void subscribe(属性属性属性,
字段(用户)
{
如果(订阅者==null){

subscribers=newhashmapJava泛型信息仅在编译时使用。然后,一旦程序运行,Java将使用对象列表

所以像这样定义您的方法,使用
,没有任何问题

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

一旦进入该方法,您就可以工作,并确保参数是您想要的类型。

在Java中使用泛型时,类型信息会被删除,并且在运行时不可用。没有优雅的方法可以解决这个问题。如果您真的需要类型信息,您必须显式地要求客户机代码传递
ar古门特。
public <N> void subscribe(Attribute<N> attr, FieldSubscriber<N> subscriber) {
List<FieldSubscriber<?>> list = subscribers.get(attr);
if (list == null) {
  list = new ArrayList<FieldSubscriber<?>>();
  subscribers.put(attr, list);
}
list.add(subscriber);