我正在尝试将一个项目切换到 Java8,但在 Eclipse Luna 和 javac 的类型推断之间遇到了奇怪的差异。使用 JDK 1.7.0_65 javac 这段代码编译得很好。 JDK 1.8.0_11 提示 toString(char[]) 和 toString(Throwable) 都匹配“toString(getKey(code, null))”;线。 Eclipse Luna 4.4 (I20140606-1215) 使用任一 JDK 都能愉快地编译它:
public class TypeInferenceTest {
public static String toString(Object obj) {
return "";
}
public static String toString(char[] ca) {
return "";
}
public static String toString(Throwable t) {
return "";
}
public static <U> U getKey(Object code, U defaultValue) {
return defaultValue;
}
public static void test() {
Object code = "test";
toString(getKey(code, null));
}
}
我认为唯一可能匹配的签名是 toString(Object)。
当然我可以简单地向 Object 添加一个转换,但我想知道 为什么 javac 不能自己推断类型(而 eclipse 可以),以及为什么 javac 考虑 Throwable 和 char[ ] 合适的匹配项,但不是对象。
这是 Eclipse 或 javac 中的错误吗? (我的意思是这里只能有一个编译器,要么编译要么不编译)
编辑:来自 javac (JDK8) 的错误消息:
C:\XXXX\Workspace\XXXX\src>javac -cp . TypeInferenceTest.java
TypeInferenceTest.java:22: error: reference to toString is ambiguous
toString(getKey(code, null));
^
both method toString(char[]) in TypeInferenceTest and method toString(Throwable) in TypeInferenceTest match
1 error
最佳答案
编译器只能检查方法签名,不能检查方法体,因此这部分是无关紧要的。
这会将您的代码“减少”为(伪代码):
public class TypeInferenceTest {
public static String toString(Object obj);
public static String toString(char[] ca);
public static String toString(Throwable t);
public static <U> U getKey(Object code, U defaultValue);
public static void test() {
Object code = "test";
toString(getKey(code, null));
}
}
另请注意 <U> U getKey(...)
真的是:<U extends Object> U getKey(...)
.
它只知道 getKey(code, null)
返回是:? extends Object
, 所以它返回 Object
的子类型,或 Object
本身。
匹配的签名有3个,分别是Object
, char[]
和 Throwable
,其中两个char[]
和 Throwable
与 Object
同等且更好地匹配,因为你要求一个 ? extends Object
.
所以它无法选择哪个是正确的,因为所有三个都匹配签名。
当您将其更改为:
public static Object getKey(Object code, Object defaultValue);
然后只有public static String toString(Object obj);
匹配,因为它与任何其他匹配更好 ? extends Object
那不等于 Object
.
编辑,我查看了问题的初衷:为什么它在 Java 7 中编译,而不是在 Java 8 中编译?
在 Java 8 中,类型推断得到了极大的改进。
而在 Java 7 中它只能推断出 getKey
返回了 Object
,它现在在 Java 8 中推断它返回一个 ? extends Object
.
当使用 Java 7 时,只有 一个 匹配,即 Object
.
为了更好地可视化更改,请考虑这段代码:
public class TypeInferenceTest {
public static String toString(Object obj) { return "1"; }
public static String toString(Throwable t) { return "2"; }
public static <U> U getKey(Object code, U defaultValue) { return defaultValue; }
public static void test() {
Object code = "test";
String result = toString(getKey(code, null));
System.out.println(result);
}
public static void main(String[] args) {
test();
}
}
在 Java 7 上它打印 1
, 在 Java 8 上它打印 2
,正是因为我在上面概述的原因。
关于java - JDK8 javac/Eclipse Luna 类型推断的差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24868245/