簡體   English   中英

List.toArray(T [])的奇數泛型行為

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

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