方法类型参数化在for循环中不起作用

时间:2015-04-02 07:29:43

标签: java

我有这种类型:

abstract class ControlGraphic { 
  //... 
}

class PrecisionControlGraphic extends ControlGraphic {
  //...
}

class AccuracyControlGraphic extends ControlGraphic {
  //...
}

我有一个返回List<T>的方法,其中TPrecisionControlGraphicAccuracyControlGraphic,具体取决于类型参数:

 private <T extends ControlGraphic> List<T> getGraphics() {
   List<T> graphics = new LinkedList<T>();
   for (ControlGraphic graphic : getGraphicsFromDB())
     graphics.add( (T) graphic);
  return graphics;
 }

以下代码正常运行:

List<PrecisionControlGraphic> precisionGraphics = getGraphics();
for (PrecisionControlGraphic graph : precisionGraphics) { ... }

我想知道为什么另一个人没有:

for (PrecisionControlGraphic graph : getGraphics()) { ... }

感谢。

1 个答案:

答案 0 :(得分:5)

方法签名是&#34;你可以将T设置为ControlGraphic&#34;的任何子类,这就是为什么赋值类型检查(因为编译器找到一个有效的类型T,实际上类型取自分配给变量)。

&#34;另一个&#34; (直接循环)不起作用,因为类型T可以是ControlGraphic的任何子类,不一定是PrecisionControlGraphic。直接循环不起作用,因为Java中的类型检查器不像函数式编程语言那样进行完全推理。 &#34;图表的类型&#34;变量必须实际上是&#34; ControlGraphic&#34;的任何子类。因为它被接受(实际上可以通过使类型成为封闭方法的类型参数来安排。)

@Adrian Leonhard指出的另一种可能性是用所需类型注释getGraphics的调用:

for (PCG graph : this.<PCG>getGraphics())

但是,基本上,对于任何这些解决方案,您都在滥用泛型。您在getGraphics中所知道的就是您正在处理ControlGraphic个对象,因此该方法应该返回List<ControlGraphic>,并且您的代码应该在代码中的位置执行显式转换。衍生类型是已知的。