2017-06-06 460 views
3

我通過「Java泛型和集合」一書的工作後,和整個這一段代碼,這是爲了編譯並沒有錯誤運行Java泛型名稱衝突類型擦除

class Overloaded { 
    public static Integer sum(List<Integer> ints) { 
     int sum = 0; 
     for (int i : ints) sum += i; 
     return sum; 
    } 
    public static String sum(List<String> strings) { 
     StringBuffer sum = new StringBuffer(); 
     for (String s : strings) sum.append(s); 
     return sum.toString(); 
    } 
} 

然而,這個例子來無法編譯有錯誤

Error:(16, 26) java: name clash: sum(java.util.List) and sum(java.util.List) have the same erasure

我可以理解爲什麼這是一個錯誤。但是,本書特別提到這是允許的,因爲編譯器可以基於返回類型區分2種方法。

然後我發現這個線程 Type Erasure and Overloading in Java: Why does this work?

這也表明,這個例子應該編譯。任何想法是什麼導致編譯失敗?

我使用的是JDK 1.8。 Java 1.8最近發生了什麼變化?如果這是相關的,我使用最新的IntelliJ IDEA作爲IDE。

+0

你可以查閱一下JDK版本的IntelliJ已經配置編譯這段代碼? –

+0

帖子引用指的是javac編譯java 6的一個bug。您使用java 8. – davidxxx

+1

@davidxxx - 這不是很清楚。它不適用於Java8或Java6嗎? –

回答

5

正如我們所知,在運行的Java擦除泛型類型,所以:

Integer sum(List ints) 
String sum(List strings) 

這樣:

Integer sum(List<Integer> ints) 
String sum(List<String> strings) 

將在運行翻譯成應該拋出這個編譯器錯誤

它編譯時沒有拋出錯誤JDK6這是一個錯誤。這個bug已經修復在JDK7,所以用編譯JDK8會拋出這個編譯錯誤。

參考:

Generic class compiles in Java 6, but not Java 7

+3

實際上,類型信息在運行時仍然存在,甚至可以通過反射來獲得它:'ParameterizedType pType =(ParameterizedType)Overloaded.class.getMethod(「sum」,List .class).getGenericParameterTypes()[0];'就是這樣,如果你要用'List'調用'sum',編譯器就不知道要綁定哪個方法。調用者將被迫使用泛型來使調用不含糊,但是這違背了使用原始類型的要點。 –