I have this types:
abstract class ControlGraphic {
//...
}
class PrecisionControlGraphic extends ControlGraphic {
//...
}
class AccuracyControlGraphic extends ControlGraphic {
//...
}
I have a method that returns a List<T>
where T
is PrecisionControlGraphic
or AccuracyControlGraphic
depending on type parameter:
private <T extends ControlGraphic> List<T> getGraphics() {
List<T> graphics = new LinkedList<T>();
for (ControlGraphic graphic : getGraphicsFromDB())
graphics.add( (T) graphic);
return graphics;
}
The code below works properly:
List<PrecisionControlGraphic> precisionGraphics = getGraphics();
for (PrecisionControlGraphic graph : precisionGraphics) { ... }
I'd like to know why this other one doesn't:
for (PrecisionControlGraphic graph : getGraphics()) { ... }
Thanks.
The method signature is saying "you can set T to any subclass of ControlGraphic", and that is why the assignment typechecks (because the compiler finds a type T that works, in fact the type is taken from the assigned-to variable).
The "other one" (direct loop) doesn't work because the type T could be any subclass of ControlGraphic, not necessarily PrecisionControlGraphic. The direct loop doesn't work because the type checker in Java does not do full inference like in functional programming languages. The type of the "graph" variable would have to literally be "any subclass of ControlGraphic" for it to be accepted (and this could actually be arranged by making the type a type parameter of the enclosing method).
Another possibility, as pointed out by @Adrian Leonhard is to annotate the call to getGraphics
with the desired type:
for (PCG graph : this.<PCG>getGraphics())
But, basically, with any of these solutions, you are misusing generics. All you know in getGraphics
is that you are dealing with ControlGraphic
objects, and so that method should return List<ControlGraphic>
, and your code should perform explicit casting at the places in the code at which the derived type is known.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With