簡體   English   中英

為什么 <T> for toArray隱藏 <E> 收集 <E> ?

[英]Why <T> for toArray hides <E> of Collection<E>?

toArray方法隱藏<E>傳遞給Collection<E>接口。 以下是方法簽名。

<T> T[] toArray(T[] a);

因為以下是可能的。 並將結果轉換為ArrayStoreException

ArrayList<String> string = new ArrayList<String>();
string.add("1");
string.add("2");
Integer intArray[] = new Integer[2];
intArray = string.toArray(intArray);

我想知道為什么會做出這樣的決定? 為什么在設計API時允許這樣的情況? 無論如何,這段代碼會導致RuntimeException

toArray方法早於泛型的引入。 toArray的原始簽名采用了任意Object[]

這是泛型的唯一方法,即接受泛型之前允許的相同輸入。 但是,采用任意T[]的優點是它可以返回它傳遞的相同數組類型。

當你調用時, intArray = string.toArray(intArray); ,你期望它構造Integer數組並返回值,因此在你的情況下返回類型是T[]Integer[]

調用這樣的方法並不意味着你能夠自動將String list轉換為Integer [] 上面的方法調用將導致java.lang.ArrayStoreException

這樣做是為了允許使用可轉換類(基類/子類),例如:

  List<Integer> list = new ArrayList<Integer>();
  list.add(1);

  Integer[] intArray = new Integer[1];
  intArray = list.toArray(intArray); //Success

  Number [] numArray = new Number[1];
  numArray = list.toArray(numArray);//Success

  Double [] dubArray = new Double[1];
  dubArray = list.toArray(dubArray); //Failure(ArrayStoreException)

當你問自己toArray()數組的類型應該是什么時,第一個最明顯的方法是將T限制為E的超類型(包括如果TE相同):這是有道理的 -能夠將元素復制到比我們的集合更通用的元素類型的數組。 但是,雖然這看起來是類型安全的(即在編譯時檢查,因此在運行時沒有異常發生)乍一看,它不是完全類型安全的 - 類型T[]的變量可以包含任何類型U[]數組U[]其中U是的子類型T 因此,即使我們將T限制為E超類型( 即使我們將T限制為與E相同),仍然可以獲得ArrayStoreException 另外,很難以這樣的方式聲明這個方法,即T只能是E的超類型,因為Java不允許類型參數的super邊界。

問題中的示例涉及T不是E的超類型。 為什么要允許這樣做? 這不是類型安全的,只有當集合的元素實際上是數組實際類型的子類型時才有效。 然而,可以認為這仍然不比我們將T限制為E的超類型的情況,或者即使我們將TE相同,因為如上所述,這些限制都不能使它成為也是類型安全的。 無論您如何聲明此方法,都可能獲得ArrayStoreException 那么,為什么不盡可能地讓它變得一般,如果不是更糟糕呢?

string.toArray(intArray)返回String類型的String ; 但是,你希望它是一個Integer類型的數組。 這將返回您提到的異常,由於類型不匹配而導致ArrayStoreException

暫無
暫無

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

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