Kie*_*old 14 java generics overloading
进入一个有趣的问题; 以下类编译:
public class Test {
public static void main(String[] args) throws Exception {
A a = new A();
B b = new B();
foo(a);
foo(b);
}
private static void foo(A a) {
System.out.println("In A");
}
private static void foo(B b) {
System.out.println("In B");
}
private static class A {}
private static class B extends A {}
}
Run Code Online (Sandbox Code Playgroud)
但是这个失败了:
public class Test {
public static void main(String[] args) throws Exception {
A<String> a = new A<>();
B b = new B();
foo(a);
foo(b);
}
private static void foo(A<String> a) {
System.out.println("In A");
}
private static void foo(B b) {
System.out.println("In B");
}
private static class A<T> {}
private static class B extends A {}
}
Run Code Online (Sandbox Code Playgroud)
有这个错误:
Test.java:8: error: reference to foo is ambiguous, both method foo(A<String>) in Test and method foo(B) in Test match
foo(b);
^
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
Run Code Online (Sandbox Code Playgroud)
我认为由于类型擦除,这些基本相同.谁知道这里发生了什么?
在泛型出现之前,Java 有类似的方法
\n\npublic class Collections\n\n public void sort(List list) {...} [1]\nRun Code Online (Sandbox Code Playgroud)\n\n用户代码可能有类似的内容
\n\npublic class MyList implements List ... [2]\n\nMyList myList = ...;\nCollections.sort(myList); [3]\nRun Code Online (Sandbox Code Playgroud)\n\n当泛型被添加到 Java 中时,我们决定将现有的类和方法转换为泛型类和方法,而不会破坏使用它们的任何代码。就难度而言,这是一项伟大的成就,但代价是使语言变得复杂且存在缺陷。
\n\n所以[1]被泛化了,但[3]仍然必须按原样编译,而不必泛化[2]。
黑客攻击位于\xc2\xa715.12.2.3
\n\n\n\n\nai可以通过方法调用转换(\xc2\xa75.3)转换为Si
\n
基本上是说,如果参数类型 (Ai) 是原始类型,则也删除参数类型 (Si) 以进行匹配。
\n\n回到您的示例,我们了解为什么foo(A<String>)被认为适用于foo(b).
然而还有另一个问题 - 是否foo(A<String>)适用于 [\xc2\xa715.12.2.2]?从规范的字面来看,答案似乎是“不”。但这可能是规范的错误。