首页 > 解决方案 > 在抽象类中使用泛型方法时返回调用类

问题描述

我有一个奇怪的问题,我无法理解。我想这是因为我不熟悉泛型。

public abstract class AbstractClass <T extends AbstractClass <T>> {

   //...

   public <T extends AbstractClass> T genericMethod(){
   //do stuff
   return (T) this;
   }
}

不将其与非抽象类一起使用

public class MyClass extends AbstractClass <MyClass> {
   //...
   public void anotherMethod() {
    //do other stuff
  }

}

到目前为止或多或少都可以(也许不理想,但还可以)。现在令人困惑的部分:

private MyClass stubWithMyClassAsReturnValue(){
   //more stuff
   return new MyClass();
}

public void test1(){
   MyCalss  myClass = stubWithMyClassAsReturnValue().genericMethod();
   myClass.anotherMethod();
   //---> works just fine
}

public void test2(){
   stubWithMyClassAsReturnValue().genericMethod().anotherMethod();
   //---> compiling error because AbstractClass does not know about anotherMethod(),
   // so genericMethod() returns AbstractClass and not MyClass
}

我想有某种隐式转换。如何让代码更流畅,摆脱这个多余的“myClass”?我很确定有一个明显的错误,但我没有看到。

标签: javagenericsabstract

解决方案


在这段代码中:

//                                this T
//                                   v
public abstract class AbstractClass <T extends AbstractClass <T>> {
//     and this T
//         v
   public <T extends AbstractClass> T genericMethod(){
   //do stuff
   return (T) this;
   }
}

突出显示的两个Ts 是不同T的 s。第一个T是类的泛型参数AbstractClass。第二个T是通用参数genericMethod。这两个Ts 不相关,并且是独立推断的。

当你这样做时:

stubWithMyClassAsReturnValue().genericMethod()

编译器知道第一个T是什么 - MyClass,但它不知道第二个T应该是什么,所以它只使用上限 - AbstractClass。但anotherMethod在 中不可用AbstractClass,因此出现错误。

您可能只需要一个T

public abstract class AbstractClass <T extends AbstractClass <T>> {

   public T genericMethod(){
       //do stuff
       return (T) this;
   }
}

推荐阅读