Reputation: 5666
I have a receiver class that puts messages in a message queue as following
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() {
...
}
}
When trying to add messages as this
public <T extends MessageBase> void processMessage(T msg) {
for (Receiver<? extends MessageBase> r : receivers) {
if (msg.getClass().equals(r.getType())) {
r.add(msg);
}
}
}
I get a
The method add(capture#3-of ? extends MessageBase) in the type
Receiver<capture#3-of ? extends MessageBase> is not applicable
for the arguments (T)
since the Receiver
class is casted to extend MessageBase
should it not work to add messages which are subclasses of MessageBase
?
Upvotes: 1
Views: 101
Reputation: 37905
Java does not know the actual parameter type of add(T msg)
as it depends on T
.
r
is defined as Receiver<? extends MessageBase>
, hence it is of an unknown type (albeit based on MessageBase
).
So Java cannot match both as they might be of a different (non-matching) type. For example msg could have a MessageBase1
type and r
could have a MessageBase2
type, which are (obviously) incompatible.
Upvotes: 1
Reputation: 46438
When you use generic's with lowerbound (? extends Type syntax) you cannot add anything into your container.
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
}
}
Refer to this answer for Why it isn't allowed
Upvotes: 2