簡體   English   中英

為什么將ArrayList的泛型轉換為超類不起作用?

[英]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> ,如果我們都可以投射單個實例BA

謝謝。

問題是這樣的:

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只能引用類型AArrayList


來自維基

與數組不同,泛型類既不是協變的也不是逆變的。 例如, 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中沒有子類型關系,即使AB的超類型,反之亦然。

如果您對Wikipedia中的詳細信息查找co / / contra-variance感興趣。

注意,在Java數組是共變型中,這意味着A[]是的超類型B[]如果A是的超類型B 這就是為什么你有時會得到奇怪的數組轉換異常的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM