2016-02-16 65 views
-2

作爲一個類的任務,我必須實現一個AbstractCollection的自定義實現,並使用泛型。我發現AbstractCollection.toArray()隱藏其默認T類型如下:爲什麼AbstractCollection.toArray()隱藏通用值T?

public <T> T[] toArray(T[] a) { ... } 

我最初以爲下面會的工作,但我被我的IDE告訴它不會覆蓋超:

@Override 
public T[] toArray(T[] a) { ... } 

所以,後來我加入<T>方法簽名,現在(雖然它會編譯)我被告知以下內容:

Array of type 'T[]' expected 

//Reports two types of suspicious calls to Collection.toArray(). 
//The first type is any calls where the type of the specified array argument 
// is not of the same type as the array type to which the result is casted. 
//Example: 
void m(List list) { 
    Number[] ns = (Number[]) 
     list.toArray(new String[list.size()]); 
} 
//The second type is any calls where the type of the specified array argument doesn't match 
// the type parameter of the collection declaration. 
//Example: 
void m(List<Number> list) { 
    Number[] ns = 
     list.toArray(new String[list.size()]); 
} 

所以,我的冷杉問題是,是否有一個很好的理由來解釋爲什麼它是以這種方式開始的?其次,這會以任何方式影響我的實施嗎?

+0

是否有負面的nancies會向我解釋爲什麼他們低估了這個問題?我沒有看到任何問題。 – agent154

+0

當您給'toArray()'方法提供'String []'時,返回值是'String []',並且與Number []'不兼容。如果你想'Number []',把它作爲參數。 – Andreas

+1

您是否在尋找http://stackoverflow.com/q/9874121/869736? –

回答

1

Collection接口聲明的方法:

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

所以你必須做的實現類相同,否則就不是給定方法的重寫,而是一個過載。

這樣做是爲了向後兼容,因爲該方法在將泛型添加到語言之前就已存在。官方的1.4文檔不再可在網上,但你可以在這裏找到它(現在):https://www.cs.duke.edu/csed/java/jdk1.4.2/docs/api/java/util/Collection.html#toArray%28java.lang.Object[]%29

記住,List<Number>List<Integer>真的只是一個List在運行時,因爲類型擦除。區別是在編譯時完成的。另一方面,Number[]Integer[]實際上在運行時是不同的,並且如果該值是錯誤的類型,將會拋出異常。如果您願意,可以從List<Integer>創建Number[]。如果您確定所有列表元素實際上都是Integer對象,您甚至可以從List<Number>創建Integer[]