2017-06-06 83 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',编译器就不知道要绑定哪个方法。调用者将被迫使用泛型来使调用不含糊,但是这违背了使用原始类型的要点。 –