Java 泛型方法继承和重写规则

我有一个具有泛型方法的抽象类,我想通过用特定类型替换泛型参数来重写泛型方法。因此,在伪代码中,我有以下内容:

public abstract class GetAndParse {
  public SomeClass var;

  public abstract <T extends AnotherClass> void getAndParse(T... args);
}

public class Implementor extends GetAndParse {
  // some field declarations

  // some method declarations

  @Override
  public <SpecificClass> void getAndParse(SpecificClass... args) {
    // method body making use of args
  }
}

但是由于某种原因,我不被允许这样做?我是否犯了某种语法错误,或者不允许进行这种继承和覆盖?具体来说,我得到了一个错误,因为eclipse IDE不断提醒我实现。@OverridegetAndParse

以下是我希望上述代码的工作方式。在我的代码中的其他地方有一个方法,它期望实现对象的实例,这特别意味着它们有一个我可以使用的方法。当我调用该实例时,编译器会检查我是否以正确的方式使用了 的特定实例,因此特别应该扩展并且应该是 。GetAndParsegetAndParsegetAndParseTTAnotherClassSpecificClass


答案 1

我们在这里拥有的是两种不同的方法,每种方法都有单独的类型参数。

public abstract <T extends AnotherClass> void getAndParse(Args... args);

这是一个具有名为 T 的类型参数的方法,其边界为 ,这意味着 允许将 的每个子类型作为类型参数。AnotherClassAnotherClass

public <SpecificClass> void getAndParse(Args... args)

这是一个类型参数名为 的方法,其限定为(意味着允许每个类型作为类型参数)。你真的想要这个吗?SpecificClassObject

类型参数是否在 内部使用?我认为问题就在那里。Args


的含义

public abstract <T extends AnotherClass> void getAndParse(T... args);

就是该方法的调用方可以决定用哪个类型参数来调用该方法,只要这是 某个子类型。这意味着实际上可以使用类型为 的任何对象调用该方法。AnotherClassAnotherClass

由于调用方可以决定类型参数,因此您不能在子类中将参数类型缩小到 - 这不是该方法的实现,而是另一个具有相同名称的方法(重载)。SpecificClass

也许你想要这样的东西:

public abstract class GetAndParse<T extends AnotherClass> {
  public SomeClass var;

  public abstract void getAndParse(T... args);
}

public class Implementor extends GetAndParse<SpecificClass> {
  // some field declarations

  // some method declarations

  @Override
  public void getAndParse(SpecificClass... args) {
    // method body making use of args
  }
}

现在,该方法实现了父类的方法。getAndParse


答案 2

你看到这个问题是因为Java泛型中称为“Erasure”的概念。Java使用“擦除”来支持向后兼容性。即不使用泛型的Java代码。

擦除过程:
编译器将首先进行类型检查,然后尽可能地删除(擦除)所有类型参数,并在必要时插入TypeCasting。

例:

public abstract <T extends AnotherClass> void getAndParse(T paramAnotherClass);

将成为

public abstract void getAndParse(AnotherClass paramAnotherClass);

在“实现者.java”类中,

代码

public <SpecificClass> void getAndParse(T paramAnotherClass)

将成为

public void getAndParse(SpecificClass paramAnotherClass){  }

编译器将看到您没有正确实现抽象方法。抽象方法和实现的方法之间存在类型不匹配。这就是您看到错误的原因。

可在此处找到更多详细信息。http://today.java.net/pub/a/today/2003/12/02/explorations.html


推荐