Java泛型:无法投射List< SubClass>列出< SuperClass> ;? [英] Java Generics: Cannot cast List<SubClass> to List<SuperClass>?
问题描述
List< DataNode> a1 = new ArrayList< DataNode>();
列表< Tree> b1 = a1; //编译错误:不兼容类型
类型DataNode是Tree的子类型。
public class DataNode implements Tree
令我惊讶的是,这对数组有效:
DataNode [] a2 = new DataNode [0];
Tree [] b2 = a2; //这是好的
这有点奇怪。任何人都可以对此作出解释吗?
你在第二种情况下看到的是数组协变。这是一个坏的事情,海事组织,使阵列内的任务不安全 - 他们可以在执行时失败,尽管在编译时很好。
在第一种情况下,想象一下代码完成了编译,然后是:
b1.add(new SomeOtherTree()) ;
DataNode node = a1.get(0);
您预计会发生什么?
你可以这样做:
List< DataNode> a1 = new ArrayList< DataNode>();
列表< ;?扩展树> b1 = a1;
...因为您只能从 b1
,并且它们保证与 Tree
兼容。您无法正确调用 b1.add(...)
,因为编译器不知道它是否安全。
查看 Angelika Langer的Java Generics常见问题的这一部分 a>获取更多信息。
Just come across with this problem:
List<DataNode> a1 = new ArrayList<DataNode>();
List<Tree> b1 = a1; // compile error: incompatible type
Where the type DataNode is a subtype of Tree.
public class DataNode implements Tree
To my surprise, this works for array:
DataNode[] a2 = new DataNode[0];
Tree[] b2 = a2; // this is okay
This likes a bit strange. Can anyone give an explanation on this?
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.
这篇关于Java泛型:无法投射List< SubClass>列出< SuperClass> ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!