Java泛型方法继承和覆盖规则

dav*_*k01 35 java inheritance abstract-class overriding generic-method

我有一个抽象类,它有一个泛型方法,我想通过用特定类型替换泛型参数来覆盖泛型方法.所以在伪代码中我有以下内容:

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
  }
}
Run Code Online (Sandbox Code Playgroud)

但由于某种原因,我不允许这样做?我是在做某种语法错误还是这种继承和覆盖是不允许的?具体来说,我收到一个错误,@Override因为eclipse IDE一直在提醒我实现getAndParse.

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

Paŭ*_*ann 32

我们这里有两种不同的方法,每种方法都有各自的类型参数.

public abstract <T extends AnotherClass> void getAndParse(Args... args);
Run Code Online (Sandbox Code Playgroud)

这是一个带有名为T的类型参数的方法,并且受到限制AnotherClass,意味着AnotherClass允许每个子类型作为类型参数.

public <SpecificClass> void getAndParse(Args... args)
Run Code Online (Sandbox Code Playgroud)

这是一个带有类型参数的方法,其名称为SpecificClassbounded Object(意味着允许每种类型作为类型参数).你真的想要这个吗?

里面使用的是类型参数Args吗?我认为问题就在那里.


的含义

public abstract <T extends AnotherClass> void getAndParse(T... args);
Run Code Online (Sandbox Code Playgroud)

是方法的调用者可以决定他想要调用方法的类型参数,只要这是一个子类型AnotherClass.这意味着实际上可以使用任何类型的对象调用该方法AnotherClass.

由于调用者可以决定类型参数,因此不能在子类中将参数类型缩小到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
  }
}
Run Code Online (Sandbox Code Playgroud)

现在该getAndParse方法实现了父类的方法.

  • 我不想要一个类型参数.我希望编译器检查并确保`SpecificClass`是`AnotherClass`的扩展. (4认同)

ken*_*ohn 13

您正在看到这个问题,因为Java Generics中称为"Erasure".Java使用"擦除"来支持向后兼容性.即不使用泛型的Java代码.

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

例:

public abstract <T extends AnotherClass> void getAndParse(T paramAnotherClass);
Run Code Online (Sandbox Code Playgroud)

会变成

public abstract void getAndParse(AnotherClass paramAnotherClass);
Run Code Online (Sandbox Code Playgroud)

在"Implementor.java"类中,

代码

public <SpecificClass> void getAndParse(T paramAnotherClass)
Run Code Online (Sandbox Code Playgroud)

会变成

public void getAndParse(SpecificClass paramAnotherClass){  }
Run Code Online (Sandbox Code Playgroud)

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

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