Let's say you're writing a generic method that takes in a list of Number
, since Number
is the minimal interface you require for the method to work.
If you write the method like this:
public void myMethod(List<Number> list) {...}
Than this works fine if users pass in a List<Number>
, but they can not pass in a List<Integer>
for example, because generics are invariant. This means that a List<Integer>
can not be assigned to a List<Number>
.
But let's say that, in your method, you're only taking things out of the list, and care only that they are any subclass of Number
(i.e. the list is a producer). For your purposes it would be fine for users to pass in a List<Integer>
.
This is where the bounded wildcard comes in.
By writing:
public void myMethod(List<? extends Number> list) {...}
You make it okay for users to pass in List<Integer>
, since it is assignable to List<? extends Number>
. But if you retrieve an element from the list, you can still be sure that it is a Number
.
One important difference though, is that you can not add a Number
to this list any more. Since the list might actually be a List<Integer>
, adding a Number
would not be type safe.