Consider the following coding problem
class A { ... }
class B extends A { ... }
List<A> aList = ...
List<B> bList = ...
List<A> getAList() {
return bList;
}
This doesn't compile. Why? Because while A is a subclass of B, List<A> is not a sublclass of List<B>. Despite that, it's quite common that you'd want to do something like this. Consider a more concrete example.
interface TreeNode { ... }
interface ContainerTreeNode extends TreeNode {
List<TreeNode> getChildren();
}
class Tree(TreeNode rootNode) { ... }
To make themselves tree-storable, other classes just implement TreeNode or ContainerTreeNode. The problem is in the implementation of ContainerTreeNode. For example,
class Employee implements TreeNode { ... }
class Manager implements ContainerTreeNode {
List<Employee> employees ...;
...
List<TreeNode> getChildren() {
return employees;
}
}
You'd like to be able to do this, but it won't compile for the reasons stated above. The solution is to use the <? extends T> idiom. Declare getChildren() as such,
List<? extends TreeNode> getChildren();
