【发布时间】:2016-07-01 13:38:19
【问题描述】:
我有一个这样的简单程序:
package test;
public class TestGenericsInheritance {
public static void main(String[] args) {}
public static abstract class A<Q>{
public void foo2(Q obj){}
public abstract <T> void foo(T obj);
}
public static class C extends A<Object>{
@Override
public <T> void foo(T obj) {}
}
public static class B extends A{
@Override
public <T> void foo(T obj) {}
}
}
如您所见,它完全没有任何作用。在 java 1.6 和 1.7 上编译此程序文件时出现以下错误:
/D:/Projects/.../test/TestGenericsInheritance.java:[24,19] test.TestGenericsInheritance.B 不是抽象的,也不会覆盖 抽象方法 foo(java.lang.Object) 在 test.TestGenericsInheritance.A /D:/Projects/.../test/TestGenericsInheritance.java:[27,25] 名称冲突: foo(T) 在 test.TestGenericsInheritance .B 和 foo(T) 在 test.TestGenericsInheritance.A 具有相同的擦除,但两者都没有 覆盖另一个 /D:/Projects/.../test/TestGenericsInheritance.java:[26,9] 方法确实 不覆盖或实现超类型中的方法
类 C 和 B 在语义上是相同的,但是类 B 不将方法 foo 识别为 A#foo 的实现。为了使此代码兼容,我必须在 B 类中使用以下签名实现方法 A#foo:
public void foo(Object obj)
我的问题是,为什么我的程序无法编译?泛型 Q 和 T 是完全独立的,为什么只有在为继承的类 A 显式指定泛型 Q 时才能实现泛型函数 A#foo?
谢谢
【问题讨论】:
-
我可以复制。更重要的是同时拥有非泛型方法和泛型方法会导致具有相同类型擦除的错误。
-
Eclipse 建议添加:
@Override public void foo(Object obj) {}到B,这实际上使它可以编译。 (1.8) -
@4castle 您的编辑使错误消息令人困惑,因为它们提到了您已删除的源文件名。
-
@KlitosKyriacou 不是我删除的。之前是主编。我会回滚。
-
@4castle 很抱歉责怪你,确实是你之前的那个人。这是一个有趣的问题,正如下面的答案所示,你应该尽量避免使用原始类型。