We need to examinate two things:
- What does the wildcard mean in the signature void doStuff(Foo<? super Bar> foo)
- What does the wildcard mean inside the method body
Java has only one very simple rule to decide the subtype relation between Foo<A> and Foo<B>: none is a subtype of the other. We say that generic types are invariant, and even if there's a rationale because the Java designers made it this way, from your point of view it's an arbitrary decision.
It's the angle brackets that confuse us, poor developers: we have no problem in accepting that FooBar and FooQoo are not related in any way; but for some reason we need to believe that Foo<Qoo> and Foo<Bar> are. No, that's not the case.
No matter how A and B relate to each other, X<A> and X<B> are not
  related.
No matter how A and B relate to each other, X<A> and X<B>
  are not related.
No matter how A and B relate to each other, X<A>
  and X<B> are not related.
Once you are convinced of the above, please observe this snippet:
List<Double> doubles = ...;
List<Integer> integers = ...;
Number firstDouble = doubles.get(0);
Number firstInteger = integers.get(0);
Calling get(0) on both lists gives us a Number-compatible object. We may want to put the call to get() in a method like getFirstOfList(list) but we just learned that such a method can't exist, because it would accept two totally unrelated types.
This is where wildcards come into play! We observe that calling get() on a List<Number>, a List<Integer>, a List<Double> (and so on) return a Number-compatible object (ie Number or a subtype of it), so there must be a way to express this at the language level. The Java designers gave us the wildcard, which works like this: when you declare
public void doStuff(List<? extends Number> arg);
it has the same effect as declaring the following infinite list:
public void doStuff(List<Number> arg);
public void doStuff(List<Integer> arg);
public void doStuff(List<Double> arg);
public void doStuff(List<Float> arg);
public void doStuff(List<BigDecimal> arg);
...
Without the device of the wildcard you'd have to write one method for each supported list type (which btw is illegal in Java, but that's another story).
The wildcard I used in my example has an upper bound, identified by the extends keyword. The snippet you pasted, instead, adopts a lower bounded wildcard in the method signature (super). Actually it may contain some errors because for example:
- you can't pass a List<Integer>todoStuff()
- you can only get an Objectfromlist.get(index)
so I will just tell you that the signature
void doStuff(List<? super Number> arg);
stands for the finite list:
void doStuff(List<Number> arg);
void doStuff(List<Object> arg);
and you can put any Number you like in a List<? super Number> but you'll only get() Object's from it.