【问题标题】:Java generics inheritance cryptic errorJava泛型继承神秘错误
【发布时间】:2013-01-07 14:44:17
【问题描述】:

我有一个接收器类,它将消息放入消息队列中,如下所示

public class Receiver<T extends MessageBase> {

  private LinkedBlockingQueue<T> messageQueue = new LinkedBlockingQueue<T>();

  public void add(T msg) {
    messageQueue.add(msg);
  }

  public void Class<T> getType() {
    ...
  }
}

当尝试添加消息时

public <T extends MessageBase> void processMessage(T msg) {
    for (Receiver<? extends MessageBase> r : receivers) {
        if (msg.getClass().equals(r.getType())) {
            r.add(msg);
        }
    }
}

我得到一个

The method add(capture#3-of ? extends MessageBase) in the type 
Receiver<capture#3-of ? extends MessageBase> is not applicable 
for the arguments (T)

既然Receiver 类被强制转换为扩展MessageBase,那么添加作为MessageBase 子类的消息是否应该不起作用?

【问题讨论】:

  • 查看我的回答here。最好记住的方法是缩写词 PECS,生产者extends,消费者super。生产者为您提供数据(例如通过get 方法),因此生产者使用extends。您想要的是一个获取数据的消费者(例如通过add 方法)。有关更多信息,请参阅我在该链接上的解释。

标签: java generics inheritance


【解决方案1】:

当您使用带有下界的泛型(?扩展类型语法)时,您无法将任何内容添加到您的容器中。

for (Receiver<? extends MessageBase> r : receivers) {
        if (msg.getClass().equals(r.getType())) {
            r.add(msg);// This is wrong, as you cannot add anything into Receiver
        }
    }

参考Why it isn't allowed这个答案

【讨论】:

    【解决方案2】:

    Java 不知道add(T msg) 的实际参数类型,因为它依赖于T

    r 被定义为Receiver&lt;? extends MessageBase&gt;,因此它属于未知类型(尽管基于MessageBase)。

    所以 Java 不能同时匹配两者,因为它们可能属于不同的(不匹配的)类型。例如 msg 可能有 MessageBase1 类型,r 可能有 MessageBase2 类型,它们(显然)不兼容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-06
      • 1970-01-01
      • 2021-10-11
      • 2011-04-25
      相关资源
      最近更新 更多