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.