What you're seeing in the second case is array covariance. It's a bad thing IMO, which makes assignments within the array unsafe - they can fail at execution time, despite being fine at compile time.
In the first case, imagine that the code did compile, and was followed by:
b1.add(new SomeOtherTree());
DataNode node = a1.get(0);
What would you expect to happen?
You can do this:
List<DataNode> a1 = new ArrayList<DataNode>();
List<? extends Tree> b1 = a1;
... because then you can only fetch things from b1
, and they're guaranteed to be compatible with Tree
. You can't call b1.add(...)
precisely because the compiler won't know whether it's safe or not.
Have a look at this section of Angelika Langer's Java Generics FAQ for more information.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…