[英]Cast to Generic type java (why unchecked)
我想知道為什么不對以下演員表進行檢查:
==更新1 ==
我知道我們在運行時有類型擦除。 注意輸入參數是一個ArrayList
而不是一些隨機列表。 ArrayList
實現List
和RandomAccess
。 我知道此強制轉換將不適用於LinkedList
或MySpecialArrayList
。 但是此方法的參數禁止這樣做。 我知道(直到人們從ArrayList
刪除List
或RandomAccess
,強制轉換在運行時不會失敗,但是為什么不檢查強制轉換?
==結束更新1 ==
private static <L extends List<GenericTokenType<?>> & RandomAccess> L castArrayList(ArrayList<GenericTokenType<?>> instance) {
return (L) instance;
}
我將此簡化為[仍警告]
private static <L extends List> L castArrayList(ArrayList instance) {
return (L) instance;
}
和[無警告]
private static List castArrayList(ArrayList instance) {
return (List) instance;
}
為什么這不起作用。 L
是一個List
(不是運行時類型,但編譯器應獲取該列表)。
重新表述這個問題:為什么它不能與通用參數返回類型一起使用? 謝謝
在第一個和第二個示例中,您將ArrayList
強制轉換為名為L
的類型。 根據一般約束, L
還必須實現List
接口。 因此, L
可以是ArrayList
, LinkedList
, Stack
或Vector
或您創建的實現List
其他類。
到目前為止一切順利,對嗎?
現在讓我們假設L
是一個ArrayList
,表達式等於:
(ArrayList) instance
顯然,這將起作用。
但是,如果L
是LinkedList
怎么辦?
(LinkedList) instance
那是行不通的,因為您不能強迫數組列表成為鏈接列表! 它們是不同的數據結構!
那為什么第三項工作呢?
在第三個示例中,您明確聲明“我希望此ArrayList
成為List
”。 這行得通,因為您要強制轉換instance
的類型是確定的。 ArrayList
實現List
,因此它必須與它兼容!
該方法將不會編譯,因為
LinkedList
是List
的子類型,並且如果不進行LinkedList
則無法工作。...請說明,我只允許ArrayList
進入,而List
其他子類則不允許
好吧,是的,您只允許將ArrayList
傳遞給方法。 但是該方法的返回類型為L
根據一般約束,我們知道L
可以是實現List
任何類型。 但是,您不能通過轉換將ArrayList
轉換為實現List
的任何類型。
L
將被刪除到List
,因為那是下限。 但是,不受約束的事實是L
從技術上可以是List
的子類,但是由於類型擦除,只能執行(最多) List
的強制轉換。 具體類型可用時,稍后將執行實際的轉換。
您也可以在字節碼中很好地看到這一點:
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: new #2 // class java/util/ArrayList
3: dup
4: invokespecial #3 // Method java/util/ArrayList."<init>":()V
7: invokestatic #4 // Method castArrayList:(Ljava/util/ArrayList;)Ljava/util/List;
// Cast is done here, after returning
10: checkcast #2 // class java/util/ArrayList
13: astore_1
14: return
public static <L extends java.util.List> L castArrayList(java.util.ArrayList);
Code:
0: aload_0
// No 'checkcast' here
1: areturn
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.