What is the difference between these two methods?
Collection<Type> getTypes();
vs
Collection<? extends Type> getTypes();
Does it matter if Type is a class or an interface? Especially, when designing an API, which version would be preferred and why?
Collection<Type> getTypes();
Here, getTypes()
must return a Collection<Type>
(e.g. ArrayList<Type>
or HashSet<Type>
).
Collection<? extends Type> getTypes();
Here, getTypes()
can return a Collection
of anything that is or extends Type
, (e.g. ArrayList<SubType>
or HashSet<SubType>
). So anything that can be returned from the first variant can also be returned from the second. In the second, however, you don't know what the type parameter of the collection actually is; you just know that it extends Type
.
As for which should be preferred, it really depends on what you're trying to do, and what makes more sense logically. Bear in mind that when you have <? extends Type>
, you don't actually know what ?
is, and this can be hindering at times; more often than not the first variant is more suitable. You can use the second variant in a base class and override it in subclasses with something that is more akin to the first, for instance:
@Override
Collection<SubType> getTypes() {
...
}
Returning with a wildcard type is generally discouraged, see the detailed reasons in the Generics FAQ. In short, it can make useless (or less useful) the returned object, because methods with parameters using the type argument can be called with 'null's only. For instance, with the Collection
:
Collection<? extends Type> collection = ...
collection.add(null); // OK
collection.add(anInstanceOfType); // Error
In this case, this prevents adding anything to the collection (which is not a bad thing, it seems someone uses this to try to make the returned collection "readonly", here), but in general this can cause problems.
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