我同意,如果不延伸B类,输出就是" 1233"但是为什么如果用A代码扩展B类代码并不编译?
public class SomeClass {
public static class A {
public void f(int x){
System.out.print("1");
}
public void f(Object x){
System.out.print("2");
}
}
public static class B // extends A {
public <T> void f(T x){
System.out.print("3");
}
}
public static void main( String[] args){
A a=new A();
B b=new B();
a.f(3);
a.f("hello");
b.f(3);
b.f("hello");
}
}
答案 0 :(得分:3)
方法签名导致名称冲突,以下两个方法签名存在名称冲突问题,因为泛型方法实际上并未覆盖前一个方法。在type erasure之后,两者都具有相同的签名。
public <T> void f(T x){...}
public void f(Object x){...}
在B
中声明的方法不会覆盖A
的方法,因为如果方法被认为被覆盖,
JLS 8.4.8.1. Overriding (by Instance Methods)
在C类中声明或继承的实例方法m C ,覆盖 来自C的另一个方法m A 在A类中声明,iff以下全部 是的:
- A是C的超类。
- C不继承m A 。
- m C 的签名是m A 签名的子签名(§8.4.2)。
的 .... 强>
以下是有效的,编译正常,
public static class A {
public <T> void f(T x) {
System.out.print("3");
}
}
public static class B extends A {
@Override
public void f(Object x) {
System.out.print("2");
}
}
答案 1 :(得分:1)
由于类型擦除问题,您无法编译上述类。
您的基类中的方法是通用的,并且与父类中的f(Object x)
匹配。这将在编译时发生。
public void f(Object x){}
public <T> void f(T x){}
请参阅this Oracle documentation有关类型删除的内容。
但是,您可以保留int
方法并且编译正常:
class A {
public void f(int x){
System.out.print("1");
}
}
public class B extends A
{
public <T> void f(T x){
System.out.print("3");
}
}
答案 2 :(得分:1)
Java泛型使用类型擦除。 javac
在解析时会发生冲突
public <T> void f(T x);
public void f(Object x);
两者在编译器javac
方面都是相同的。
添加另一个factorize
:
class Test{
void add(Set<Integer> ii){}
void add(Set<String> ss){}
}
This limitation is part of the language syntax, not the Java runtime itself. Essentially, this rule is intended to avoid conflicts in legacy code that still uses raw types.
请参考上述答案。