簡體   English   中英

為什么可以強制轉換泛型類?

[英]Why is it possible to cast generic class?

Java 泛型是不變的,所以不可能進行這樣的轉換:

List<Object> li = (List<Object>)new ArrayList<Integer>();

但是在第 4 行的以下代碼中,我可以從List<Integer>List<T> ,其中T可以是任何類型。 為什么允許這種類型的演員表?

我知道它會生成有關未經檢查的強制轉換的警告,但關鍵是這種強制轉換在參數化方法中是可能的,但在普通代碼中是不可能的。 記住泛型是不變的,為什么允許它? 在具有List<Integer>普通代碼中,我只能將其轉換為List<Integer> ,這沒有意義,其他轉換是非法的。 那么允許像第 4 行那樣進行強制轉換有什么意義呢?

我知道泛型類型在編譯時被刪除,它以List xlist = (List)list結尾,但在刪除這些類型之前,很明顯不應允許這種強制轉換,除非它僅在有人通過 Integer 作為的情況下被接受el沒有多大意義。

class Test {

    public static <T> void t(List<Integer> list, T el) {
        List<T> xlist = (List<T>)list; //OK
        xlist.add(el);
    }

    public static void main(String[] args) {

        List<Integer> list = new ArrayList<>();
        t(list, "a");
        t(list, "b");

        //prints [a, b] even if List type is Integer
        System.out.println(list);

    }
}

在 Java 中,執行在編譯時已知始終不正確或始終正確的顯式強制轉換是編譯錯誤。 在編譯時已知從List<Integer>List<Object>轉換總是不正確的,因此這是不允許的。 List<Integer>List<T>在編譯時並不知道總是不正確的——如果TInteger則是正確的,而T在編譯時不知道。

我想答案是這個轉換是可能的,因為Integer可以作為參數el傳遞,在這種情況下,轉換是正確的。 在 Integer 以外的所有其他類型的情況下,它將是非法轉換。 但是正如我在泛型中看到的那樣,如果至少有一種類型可以提供正確的轉換( Integer ),那么編譯器不會給出錯誤,而是警告,即使所有其他情況都無效。

Object 是 Integer 類的超類。 List<Object>不是List<Integer>類的超類,但此外,如果您希望List<Object>引用List<Integer>您可以使用小丑符號 (?)。

List<?> list1 = new List<Object>();
List<?> list2 = new List<Integer>();
list1 = list2;

暫無
暫無

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

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