In Java, assume I have the following class Container that contains a list of class Items:
public class Container<T>
{
private List<Item<? extends T>> items;
private T value;
public Container(T value)
{
this.value = value;
}
public void addItem(Item<? extends T> item)
{
items.add(item);
}
public void doActions()
{
for (Item<? extends T> item : items)
{
item.doAction(value);
}
}
}
public abstract class Item<T>
{
public abstract void doAction(T item);
}
Eclipse gives the error:
The method doAction(capture#1-of ? extends T) in the type Item is not applicable for the arguments (T)
I’ve been reading generics examples and various postings around, but I still can’t figure out why this isn’t allowed. Eclipse also doesn’t give any helpful tips in its proposed fix, either. The variable value is of type T, why wouldn’t it be applicable for ? extends T?.
Take a look at the following program
As you said, the (A) line does not compile. If this line were legal then, at runtime, the program will pass a
Doubleobject to thecn.set()call wherecn‘s dynamic type isCell<Integer>.When execution subsequently arrives at (B),
ci.get()will return aDoubleobject—the one that was passed in (A)—were the declaration ofcisays that itsget()method is guaranteed to return anInteger. In order to prevent this conundrum (which actually breaks the JVM’s strong typing philosophy), the compiler disallows assignment fromTto<? extends T>.