【问题标题】:returning calling class when using generic method in abstract class在抽象类中使用泛型方法时返回调用类
【发布时间】:2020-10-02 06:44:12
【问题描述】:

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

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”?我很确定有一个明显的错误,但我没有看到。

【问题讨论】:

  • 你的案例是described here类型参数的更多技巧标题下,但整篇文章值得一读
  • @pafauk。谢谢你,但你链接到这个页面。:)
  • 哎呀,here it is。现在应该可以工作了:)

标签: java generics abstract


【解决方案1】:

在这段代码中:

//                                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 是不同的Ts。第一个T 是类AbstractClass 的通用参数。第二个TgenericMethod 的通用参数。这两个T没有关系,是独立推断的。

当你这样做时:

stubWithMyClassAsReturnValue().genericMethod()

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

您可能只需要一个T

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

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

【讨论】:

  • 谢谢伙计!那解决了它。你的解释也很有帮助。你是对的,我把一些东西弄混了,有些 T 太多了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 2012-12-10
相关资源
最近更新 更多