[英]Odd generics behaviour of List.toArray(T[])
我遇到了一些非常基本但今天非常困惑的事情。 我需要將列表轉換為數組。 該列表包含String
實例。 使用List.toArray(T[])
完美示例,因為我想要一個String[]
實例。 但是,如果沒有將結果顯式地轉換為String[]
,它將無法工作。
作為測試場景,我使用了以下代碼:
import java.util.Arrays;
import java.util.List;
public class MainClass {
public static void main(String args[]) {
List l = Arrays.asList("a", "b", "c");
String stuff[] = l.toArray(new String[0]);
System.err.println(Arrays.asList(stuff));
}
}
哪個不編譯。 它幾乎是javadoc中示例的精確副本,但編譯器說如下:
MainClass.java:7: incompatible types
found : java.lang.Object[]
required: java.lang.String[]
String stuff[] = l.toArray(new String[0]);
^
如果我向String[]
添加一個強制轉換,它將編譯並運行完美。 但是當我查看toArray方法的簽名時,這不是我所期望的:
<T> T[] toArray(T[] a)
這告訴我,我不應該投。 到底是怎么回事?
編輯:
奇怪的是,如果我將列表聲明更改為:
List<?> l = Arrays.asList("a", "b", "c");
它也有效。 或List<Object>
。 所以它不必像建議的那樣是List<String>
。 我開始認為使用原始List
類型也會改變該類中泛型方法的工作方式。
第二次編輯:
我想我現在明白了。 Tom Hawtin在下面的評論中所寫的內容似乎是最好的解釋。 如果以原始方式使用泛型類型,則編譯器將擦除該實例中的所有泛型信息。
您忘了為List指定type參數:
List<String> l = Arrays.asList("a", "b", "c");
在這種情況下,你可以寫安全:
String[] a = l.toArray(new String[0]);
沒有任何演員。
或者做
List<?> l = Arrays.asList("a", "b", "c");
還是很奇怪
List<String> l = Arrays.asList("a", "b", "c");
這將使它編譯,你使用泛型來說“這是一個字符串列表”,所以toArray方法知道要返回哪種類型的數組。
那是因為你的列表包含對象,而不是字符串。 如果您將列表聲明為List<String>
,編譯器會很高興。
沒有聲明類型的List
將默認為“對象List<?>
”,而List<?>
表示“未知列表”。 在泛型類型的世界中,“對象列表”與“字符串列表”不同,但編譯器不能對“未知列表”說同樣的事實。 如果您已將其聲明為未知,那么就編譯器而言,那沒關系。
重點是將某些東西稱為通配符? 不同於將其聲明為Object。 在這里閱讀有關通配符的更多信息
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.