我有这种类型:
abstract class ControlGraphic {
//...
}
class PrecisionControlGraphic extends ControlGraphic {
//...
}
class AccuracyControlGraphic extends ControlGraphic {
//...
}
我有一个返回List<T>
的方法,其中T
为PrecisionControlGraphic
或AccuracyControlGraphic
,具体取决于类型参数:
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()) { ... }
感谢。
答案 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>
,并且您的代码应该在代码中的位置执行显式转换。衍生类型是已知的。