2013-01-07 83 views
1

我有把消息在消息隊列如下Java泛型繼承神祕的錯誤

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類被鑄造爲延伸如果它不工作添加消息是的子類?

+1

看到我的答案[here](http://stackoverflow.com/questions/12604477/use-of-extends-and-super-in-collection-generics/12605337#12605337)。要記住的最好方法是縮寫PECS,生產者'延伸',消費者'超級'。生產者給你提供數據(例如通過'get'方法),所以生產者使用'extends'。你想要的是一個需要數據的消費者(例如通過「add」方法)。請參閱我在該鏈接的解釋以獲取更多信息。 – Brian

回答

2

當你用lowerbound(?extends Type語法)使用泛型時,你不能在容器中添加任何東西。

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

1

Java不知道的add(T msg)實際的參數類型,因爲它依賴於T

r定義爲Receiver<? extends MessageBase>,因此它是未知類型(儘管基於)。

所以Java不能匹配兩者,因爲它們可能是不同的(不匹配)類型。例如,msg可能有MessageBase1類型,而r可能有MessageBase2類型,這顯然是不兼容的。