【发布时间】:2015-08-11 20:54:35
【问题描述】:
考虑以下程序:
public class GenericTypeInference {
public static void main(String[] args) {
print(new SillyGenericWrapper().get());
}
private static void print(Object object) {
System.out.println("Object");
}
private static void print(String string) {
System.out.println("String");
}
public static class SillyGenericWrapper {
public <T> T get() {
return null;
}
}
}
它在 Java 8 下打印“String”,在 Java 7 下打印“Object”。
我原以为这在 Java 8 中会产生歧义,因为这两个重载方法都匹配。为什么编译器在JEP 101 之后选择print(String)?
无论是否合理,这都会破坏向后兼容性,并且在编译时无法检测到更改。升级到 Java 8 后,代码只是偷偷摸摸地表现不同。
注意:SillyGenericWrapper 被命名为“傻”是有原因的。我试图理解为什么编译器的行为方式是这样,首先不要告诉我愚蠢的包装器是一个糟糕的设计。
更新:我还尝试在 Java 8 下编译和运行该示例,但使用的是 Java 7 语言级别。该行为与 Java 7 一致。这是意料之中的,但我仍然觉得需要验证。
【问题讨论】:
-
我用 jdk 1.8.0 或 jdk1.8.45 尝试了 eclipse,它打印出 Object
-
我在 Ideone.com 上获得了字符串(使用 sun-jdk-8u25)。
-
我会在问题标题和正文中将覆盖更改为重载。不涉及覆盖。
-
@Giovanni:我想我们应该在未来几年禁止 Java 8 相关问题中的任何 Eclipse 特定声明......(不要误会我的意思,我真的希望将 Eclipse 与 Java 8 一起使用)
-
我在 Oracle jdk1.8.0_45 上获得了
String。
标签: java generics java-8 language-lawyer