Javagenerics方法inheritance和覆盖规则

我有一个具有generics方法的抽象类,我想通过将特定类型替换为generics参数来覆盖generics方法。 所以在伪代码中我有以下内容:

public abstract class GetAndParse { public SomeClass var; public abstract  void getAndParse(T... args); } public class Implementor extends GetAndParse { // some field declarations // some method declarations @Override public  void getAndParse(SpecificClass... args) { // method body making use of args } } 

但由于某种原因,我不允许这样做? 我是在做某种语法错误还是这种inheritance和覆盖不允许? 特别是我收到关于@Override的错误,因为eclipse IDE一直在提醒我实现getAndParse

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

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

 public abstract  void getAndParse(Args... args); 

这是一个名为T的类型参数的方法,由AnotherClass ,这意味着允许AnotherClass每个子类型作为类型参数。

 public  void getAndParse(Args... args) 

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

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


编辑:

的含义

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

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

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

也许你想要这样的东西:

 public abstract class GetAndParse { public SomeClass var; public abstract void getAndParse(T... args); } public class Implementor extends GetAndParse { // some field declarations // some method declarations @Override public void getAndParse(SpecificClass... args) { // method body making use of args } } 

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

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

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

例:

 public abstract  void getAndParse(T paramAnotherClass); 

会变成

 public abstract void getAndParse(AnotherClass paramAnotherClass); 

在“Implementor.java”类中,

代码

 public  void getAndParse(T paramAnotherClass) 

会变成

 public void getAndParse(SpecificClass paramAnotherClass){ } 

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

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

不,它无效。 如果有一个GetAndParse参考的人用另一个扩展AnotherClass类调用它会发生什么?

当有人引用类型GetAndParse并尝试调用getAndParse方法时,这变得毫无意义。 如果Cat和Dog扩展了AnotherClass。 我希望能够用Cat或Dog调用GetAndParse#getAndParse。 但是实现已经尝试限制它并使其兼容性降低!

你不能覆盖到特定的类型T,因为实际上(如果你愿意,在字节码级别)只有一个方法getAndParse因为类型擦除(参见其他答案):

  public abstract void getAndParse(AnotherClass... args); // (1) 

对于每种类型的T,使用相同的方法。

你可以重载它(我认为):

  public void getAndParse(SpecificClass... args); // (2) 

但这不会与(1)ant不同,它不会被通用代码调用:

  T x = whatever; object.getAndParse(x); // Calls (1) even if T is derived from SpecificClass