2013-06-20 62 views
4

我試着使用Java創建重載方法:Java的泛型和方法簽名

private BasesResponse getResponse(List<ClassA> classA) { 
... 
} 

private BasesResponse getResponse(List<ClassB> classB) { 
    ... 
} 

但是Eclipse抱怨:方法getResponse(List<ClassA>)具有相同的擦除getResponse(List<E>)在類型BasisInformationEndpoint另一種方法。

我認爲方法簽名是方法名稱+參數列表....但List<ClassA>如何可以List<ClassB>?對我來說沒有意義。

+3

閱讀關於類型擦除:http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#Type%20Erasure –

+0

它確實有意義,這是一個很好的問題。我相信有人會爲你輸入一個很好的解釋。 –

+0

一旦你瞭解[Type Erasure](類型擦除)(http://docs.oracle.com/javase/tutorial/java/generics/erasure.html),你就會明白爲什麼它是 –

回答

2

泛型類型(<...>)僅在編譯階段出現才用於靜態類型。

一旦編譯,這些類型被「擦除」,並且List<ClassA>實質上變成List。因此,你可以看到,當這種情況發生時,你的兩個功能變得完全相同

這被稱爲類型刪除,正如評論者所提到的那樣。

5

的Java generic type erasure將使

private BasesResponse getResponse(List classA) { 
... 
} 

private BasesResponse getResponse(List classB) { 
    ... 
} 

後類型擦除它是編譯器相同。

1

這是不可能的。爲了向後兼容,泛型參數在運行時被丟棄(不像在C#中)。這被稱爲類型擦除。因此在運行時,List<Whatever>只是一個List。這意味着你的兩個方法都有一個BasesResponse getResponse(List)的原型,這是一個編譯錯誤。

1

通用方法參數中的Java編譯器也是erases type parameters

您可能會看到兩個參數爲不同類型的,但是當<>被刪除JVM將看到兩種方法的參數的類型。

因此,重載失敗。

1

泛型類型擦除:

這樣做的原因實際上是由於仿製藥,List<ClassA>List<ClassB>的Java 1.5之前沒有發現任何仿製藥,名單被宣佈爲是。正如List。這意味着你可以把任何東西在指定的列表中,這將是合法的只添加ObjectStringClassAListener等,以一個列表中。泛型被引入用於指定它們將獲得的類型的集合。這就是:List<ClassA>List<String>等也發揮了作用。但是爲了保留那些創建系統預泛型時間的人的遺留系統,這將是一個問題,泛型只是強加編譯時間,但是在運行時它仍然是相同的基礎List之前。

因此,要回答你的問題,到Eclipse這是兩個同樣的方法簽名接收一個參數:

private BasesResponse getResponse(List classX) { ... }

0

因爲對於的JavaList<ClassA>List<ClassB>類型參數是一樣的List<E> 。如果ClassAClassB具有相同的父級,請使用getResponse(List<? extends ClassABParent> param)

0

這是因爲編譯器還支持傳統的代碼,這就是爲什麼它抹去泛型類型considering.you可以找到同樣的問題在here

1

回答這是因爲通過type erasure會後兩種方法就出來是這樣的:

private BasesResponse getResponse(List classA) { 
... 
} 

private BasesResponse getResponse(List classB) { 
    ... 
} 

兩個具有相同簽名的相同方法。哪一個不是重載,而是一個編譯時錯誤。