为什么将 ArrayList 的泛型转换为超类不起作用?
有人可以向我解释为什么下面的代码示例中标记为 //this line 给出编译错误(为什么?)
的行不起作用吗?
import java.util.ArrayList;
public class GenericCastCheck {
class A{
}
class B extends A{
}
public static void main(String[] args) {
A aObject = new A();
B bObject = new B();
//this line works fine
aObject = bObject;
//this line gives a compile (expected)
bObject = aObject;
ArrayList<A> aList = new ArrayList<A>();
ArrayList<B> bList = new ArrayList<B>();
//this line gives a compile error (why?)
aList = bList;
//this line gives a compile error (expected)
bList = aList;
}
}
具体来说,当我们说 bList
是 ArrayList
类型时,是不是意味着它的每个元素都是 B
的实例?如果是这样,那么如果我们可以将 B
的各个实例强制转换为 A
,那么将其强制转换为 ArrayList
会出现什么问题?
谢谢。
Can someone please explain to me why the line marked //this line gives a compile error (why?)
in the following code sample does not work?
import java.util.ArrayList;
public class GenericCastCheck {
class A{
}
class B extends A{
}
public static void main(String[] args) {
A aObject = new A();
B bObject = new B();
//this line works fine
aObject = bObject;
//this line gives a compile (expected)
bObject = aObject;
ArrayList<A> aList = new ArrayList<A>();
ArrayList<B> bList = new ArrayList<B>();
//this line gives a compile error (why?)
aList = bList;
//this line gives a compile error (expected)
bList = aList;
}
}
Specifically, when we say that bList
is of type ArrayList<B>
, does it not mean that each element of it is an instance of B
? If so, then what is the problem in casting it to ArrayList<A>
, if we can cast individual instances of B
to A
?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题是这样的:
如果您对数组执行相同的操作,则会在运行时在第 4 行中收到 ArrayStoreException。对于泛型集合,决定在编译时防止这种情况发生。
The problem is this:
If you do the same thing with arrays, you get an ArrayStoreException in line 4 at runtime. For generic collections, it was decided to prevent that kind of thing at compile time.
因为通用是严格的。它们不是协变的
ArrayList
aList 只能引用A
类型的ArrayList
来自 wiki
Because generic are strict. they aren't covarient
ArrayList<A>
aList can only refer to anArrayList
of typeA
From wiki
Animesh,
即使 B 类是 A 的子类型,ArrayList < B>不是 ArrayList < 的子类型A>.它与 B[] 位于同一行,不是 A[] 的子类型。这是两个独立的、不相关的类型。
Animesh,
Even though class B is subtype of A, ArrayList< B > is not a subtype of ArrayList < A >. Its on the same line as in B[] is not subtype of A[]. These are two independent unrelated types.
因为在 Java 中,
C
和C
之间没有子类型关系,即使A
是B
的超类型,反之亦然。如果您对详细信息感兴趣,请在维基百科中查找协方差/逆变方差。
请注意,在 Java 中数组是协变的,这意味着如果
A
是B
。这就是为什么有时会遇到数组奇怪的强制转换异常的原因。Because there is no subtype relation in Java between
C<A>
andC<B>
, even ifA
is a supertype ofB
or vice versa.If your interested in the details lookup co- / contra-variance in Wikipedia.
Note, that in Java arrays are co-variant, which means
A[]
is a supertype ofB[]
ifA
is a supertype ofB
. That is the reason why you sometimes get strange cast exception with arrays.