[英]Java generics type erasure of method parameters
我從Joshua Bloch給出的谷歌I / O益智游戲中得到了這個。 這是代碼
public class Glommer<T> {
String glom(Collection<?> obj){
String result = "";
for(Object o : obj){
result += o;
}
return result;
}
int glom(List<Integer> ints){
int result = 0;
for(int i : ints){
result += i;
}
return result;
}
public static void main(String args[]){
List<String> strings = Arrays.asList("1", "2", "3");
System.out.println(new Glommer().glom(strings));
}
這個main方法拋出一個異常,因為new Glommer
是一個原始類型,因此new Glommer
中的所有泛型Glommer
被擦除,所以它最終調用int glom(List<Integer> ints)
而不是String glom(Collection<?> obj)
。
我的問題是,即使我將glom()
稱為new Glommer<Integer>().glom(strings)
也不應該調用int glom(List<Integer> ints)
方法,因為由於類型擦除,這種方法是有效的int glom(List ints)
和strings
是List
not Collection
類型?
被調用的方法是在編譯時定義的,而不是在運行時定義的。
如果向構造函數調用添加參數,編譯器將有足夠的信息知道它必須調用第一個方法。 否則,就好像仿制葯不存在一樣。 在這兩種情況下,被調用的方法在運行時將始終保持不變。
編輯有些人似乎有疑問,所以這是另一個例子:
public class Test {
private static void test(Object object) {
System.out.println("Object method");
}
private static void test(Integer integer) {
System.out.println("Integer method");
}
public static void main(String[] args) {
Object object = Integer.valueOf(0);
test(object);
}
}
結果是:
Object method
您將Integer傳遞給您的方法,但編譯器在編譯時知道的所有內容都是它是一個對象。 即使Object實際上是一個Integer,jvm也不會自動更改方法調用。
您可以閱讀有關原始類型的更多信息以完全理解它
基本上,原始類型是使用遺留代碼,原始類中的任何東西都將變為原始本身,在這種情況下是那兩種方法。
因此,當它是raw時,有一個方法可以獲取List
和一個Collection
因此它被稱為List
one,如果它不是raw,那么方法也不是raw,它會調用Collection
一個,因為它有額外的信息
這是因為當沒有泛型Generic<Type>()
調用new Glommer()
時,所有類型的匹配都將從類中刪除。
由於strings變量是List
,如果它沒有任何泛型<Type>
那么它將匹配glom(List ints)
。 類型檢查直到稍后才完成。
當我們創建new Glommer<AnyType>
,所有類型都保留在原位,所以當我們傳遞我們的strings
變量時,它會進行類型檢查。 編譯器現在可以檢查它是否是List<Integer>
,但不會將其傳遞給glom(Collection<?> obj)
方法。
希望這有幫助,如果您需要,請詢問任何澄清!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.