[英]Casting ArrayList<SuperClass> to ArrayList<SubClass>
[英]Why does casting an ArrayList 's generic to a superclass not work?
有人可以向我解释为什么标记为//this line gives a compile error (why?)
在下面的代码示例中不起作用?
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
的实例? 如果是这样,那么它是什么铸造的问题ArrayList<A>
,如果我们都可以投射单个实例B
到A
?
谢谢。
问题是这样的:
ArrayList<A> aList = new ArrayList<A>();
ArrayList<B> bList = new ArrayList<B>();
aList = bList; // if this were valid...
aList.add(new A()); // ...what should happen here?
B b = bList.get(0); // ...and here?
如果对数组执行相同的操作,则会在运行时在第4行中获得ArrayStoreException。 对于通用集合,决定在编译时阻止这种事情。
因为通用是严格的。 他们不是共同的
ArrayList<A>
aList只能引用类型A
的ArrayList
来自维基
与数组不同,泛型类既不是协变的也不是逆变的。 例如,
List<String>
和List<Object>
都不是另一个的子类型:// a is a single-element List of String List<String> a = new ArrayList<String>(); a.add("foo"); // b is a List of Object List<Object> b = a; // This is a compile-time error
但是,泛型类型参数可以包含通配符(仅使用一次的额外类型参数的快捷方式)。 示例:由于需要对任何对象的列表进行操作的方法,因此可以对对象执行的唯一操作是可以保证类型关系安全的操作。
// a is a single-element List of String List<String> a = new ArrayList<String>(); a.add("foo"); // b is a List of anything List<?> b = a; // retrieve the first element Object c = b.get(0); // This is legal, because we can guarantee // that the return type "?" is a subtype of Object // Add an Integer to bbadd(new Integer (1)); // This is a compile-time error; // we cannot guarantee that Integer is // a subtype of the parameter type "?"
通配符也可以绑定,例如分别为上限和下限“
? extends Foo
”或“? super Foo
”。 这允许改进允许的性能。 示例:给出一个List<? extends Foo>
List<? extends Foo>
,然后可以检索元素并将其安全地分配给Foo
类型(协方差)。 鉴于List<? super Foo>
List<? super Foo>
,然后可以安全地添加Foo
对象作为元素(逆变)。
的Animesh,
即使B类是A的子类型,ArrayList <B>也不是ArrayList <A>的子类型。 它与B []在同一行上不是A []的子类型。 这是两种独立的不相关类型。
因为在C<A>
和C<B>
之间Java中没有子类型关系,即使A
是B
的超类型,反之亦然。
如果您对Wikipedia中的详细信息查找co / / contra-variance感兴趣。
注意,在Java数组是共变型中,这意味着A[]
是的超类型B[]
如果A
是的超类型B
。 这就是为什么你有时会得到奇怪的数组转换异常的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.