[英]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.