Java泛型扩展返回类型的方法

Ble*_*eek 5 java generics methods return-type

看看这三个班级.Minatchi允许自己扩展,以便其方法的返回类型也可以扩展.为了说明,我使用了静态方法.

public class Minatchi<T extends Minatchi<?>>{

  static public <T extends Minatchi<?>>
    List<T> listAll(){
      return
        (List<T>) query();
  }
}
Run Code Online (Sandbox Code Playgroud)

所以我把Minatchi子类化为Lady

public class Lady
extends Minatchi<Lady>{

}
Run Code Online (Sandbox Code Playgroud)

这是可疑行为发生的地方.

public class HelloMinatchi{

  private void listA(){
    List<Lady> uvs = Lady.listAll();
    for (Lady uv: uvs){
      logger.info(uv.getName() );
    }
  }

  private void listB(){
    for (Lady uv: Lady.listAll()){
      logger.info(uv.getName() );
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

方法listA和listB基本相同.listA将列表放入中间变量uvs,而listB直接将listAll放入for循环头.

但是,对于listB,编译器抱怨无法将Minatchi <?>转换为Lady.

所以这个问题是关于Java泛型的设计完整性.另一个仿制药抱怨.

这是一个深思熟虑的设计特性还是Java仿制药设计人员不知道如何解决的无意设计错误.如果故意,他们为什么这样做?如果有bug,他们是否打算解决它?

或者这是我的个人问题,我不知道更好的方式来声明泛型?如果是这样,请告诉我如何.

(我使用了一个通用的Minatchi类,因为我也有非静态方法暴露给类扩展,我在问题中遗漏了.)

Boz*_*zho 5

静态方法不从类中获取泛型类型定义.即该listAll()方法不知道Lady(in extends Minatchi<Lady>).

它的返回类型由表达式的左侧推断:

  • listA()左侧定义了它所期望的List<Lady>
  • listB()forEach循环看起来它应该也期望a Lady,但似乎编译器没有正确指示使用forEach循环.

listB()工作的方法是告诉它使用什么泛型类型:

for (Lady uv : Lady.<Lady>listAll()) {..}
Run Code Online (Sandbox Code Playgroud)