import java.util.Collection;
public abstract class A {
public class R<T> { }
public abstract <X> R<X> get1();
public abstract <X> R<X> get2(Collection<String> p);
public abstract <X> R<X> get3(Collection<Integer> p);
public class B extends A {
@Override
public R<Object> get1() {
return null;
}
@Override
public R<Object> get2(Collection<String> p) {
return null;
}
@Override
public <Object> R<Object> get3(Collection<Integer> p) {
return null;
}
}
}
get1
方法运行正常,但get2
存在编译错误:
A.B类的
get2(Collection)
方法必须覆盖或实现一个超类型方法。
get3
可以编译,但当然会有警告:
类型参数Object隐藏了类型Object。
编辑:
抱歉,我的例子不够清晰。 因此,这里是一个新的例子来回应您的答案中的一些观点。
public abstract class A {
public abstract class R<T> { }
public abstract <X> R<X> get();
public abstract <Y> R<Y> get2(Collection<String> p);
public abstract <Z> R<Z> get3(Collection<Integer> p);
public class B extends A {
@Override
public R<String> get() {
return null;
}
@Override
public R<Double> get2(Collection<String> p) {
return null;
}
@Override
public <V> R<V> get3(Collection<Integer> p) {
return null;
}
}
}
get2
的编译错误与上述相同,而对于get
,则会有一个明显的类型安全警告,我期望在get2
上也会出现。- 我希望每个方法都有自己的类型,因此类类型不是解决方案。
- 对于这个例子来说使用 Object 是个糟糕的决定,但这不是我的观点,旧的
get3
存在类型隐藏问题,如上所述。 - 问题在于签名,就像 lexicore 所说。因此我将评论他的答案。
Collection<String>
替换为String
,错误就会消失,因此似乎是由于参数类型是泛型引起的。可能是一个 bug,但 Oracle javac 和 ECJ 有相同的行为,所以更可能是由于 Java 语言规范中一些晦涩的泛型签名解析规则导致的。 - Sean Van Gorder