The short explanation: it was a mistake to allow it originally for Arrays.
The longer explanation:
Suppose this were allowed:
List<DataNode> a1 = new ArrayList<DataNode>();
List<Tree> b1 = a1; // pretend this is allowed
Then couldn't I proceed to:
b1.add(new TreeThatIsntADataNode()); // Hey, b1 is a List<Tree>, so this is fine
for (DataNode dn : a1) {
// Uh-oh! There's stuff in a1 that isn't a DataNode!!
}
Now an ideal solution would allow the kind of cast you want when using a variant of List
that was read-only, but would disallow it when using an interface (like List
) that's read-write. Java doesn't allow that kind of variance notation on generics parameters, (*) but even if it did you wouldn't be able to cast a List<A>
to a List<B>
unless A
and B
were identical.
(*) That is, doesn't allow it when writing classes. You can declare your variable to have the type List<? extends Tree>
, and that's fine.