具有类型列表和继承的方法

7

我有一个方法,它的参数是一个带类型的List,该方法继承自另一个(带类型的)类。

让我们简化一下:

public class B<T> {
  public void test(List<Integer> i) {
  }
}

B类有一个无用的通用类型T,而test()需要一个整数列表。

现在如果我这样做:

public class A extends B {
  // don't compile
  @Override
  public void test(List<Integer> i) {
  }
}

我遇到了一个错误 "The method test(List) of type A must override or implement a supertype method",这不应该发生。
但是如果去掉列表类型的声明,就可以解决问题……虽然这并不依赖于类的泛型。
public class A extends B {
  // compile
  @Override
  public void test(List i) {

并且将无用的通用类型定义为使用类型列表

public class A extends B<String> {
  // compile
  @Override
  public void test(List<Integer> i) {

我不知道应该怎么办,B的泛型不应该影响test()列表的类型。有人知道发生了什么吗?

谢谢


我相信你的答案在这里 - nobeh
传统上,大写字母V的“Void”用于您不想使用的通用参数。例如,在使用java.security.PreivilegedAction时不返回值(返回null-它是唯一有效的Void引用)。 - Tom Hawtin - tackline
2个回答

9

你正在扩展B的原始类型,而不是泛型类型。原始类型实际上没有 test(List<Integer> i) 方法,而是一个 test(List) 方法。

如果您切换到原始类型,则所有泛型都将被替换为原始类型,无论其类型是否已填充。

要正确执行此操作,请执行以下操作:

 public class A<T> extends B<T>

这将使用通用类型B<T>,其中包括您想要覆盖的方法。


谢谢。这并不是很合乎逻辑,因为我们没有使用T,但Java的泛型存在一些设计缺陷,我们必须处理。 - PomPom

1

当您使用没有泛型的类(并且以原始方式使用)时,类方法中的所有泛型都会被忘记。

由于这个原因,当您在第二种情况下通知泛型类型时,它可以正常工作。

这个:

class T<G> {
   public void test(G g);
}

在这种情况下:
class A extends T {
}

会长成这样:

class T {
   public void test(Object g);
}

这是一个在2011年Google IO上展示的Java难题,你可以在这里观看视频。

真正的问题在于我没有使用 G 而是一个具体的类。不管怎样,我得到了答案。 - PomPom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接