Because it might only allow objects of type B.
A classic question, answered a million of times. Non-intuitive, but also not a design bug of Java.
Here is the classic example: let A be Fruit.
Can I put an Apple into a Set<? extends Fruit>?
No, because it could be a Set<Banana> which obviously must not contain apples.
? extends Fruit says some specific kind of fruit, and not "any kind of fruit". Then it would be a Set<Fruit> which indeed can take any kind of Fruit.
As a rule of thumb:
- when putting ? super Fruitis convenient. It takes "at least" fruits
- when getting ? extends Fruitis convenient. It may return only one kind of fruit, but they will all be fruit.
Consider this method:
public static double computeAverage(Collection<? extends Number> col) {
    double sum = 0.;
    for (Number n : col) {
      sum += n.doubleValue();
    }
    return sum / n.size();
}
This method can work with List<Integer>. Because it does not put Double into the list, but only takes Number objects out.
public static void put(Collection<? super Number> col, Number n) {
    col.put(n);
}
Here, we have the opposite case. We need a list that accepts arbitrary numbers (otherwise, we could not put the unspecific number in it). It may accept more, though:
put(new List<Object>(), (Double) 1.);
is valid, because I may put doubles into a list of Objects.
But the compiler correctly prevents put( new List<Integer>(), (Double) 1.).
It can get much messier than that:
public static <I,O> void transfer(Collection<? extends I> input,
                                  Collection<? super O> output,
                                  Converter<? super I, ? extends O> converter) {
  for (I inobj : input) {
    O outobj = converter.convert(inobj);
    output.put(outobj);
  }
}
But the compiler may be unable to figure out I and O automatically for you every time.