Short answer
Use <? extends T> when a structure produces T values you only read (you can get a T out but can't add, since the exact subtype is unknown), and <? super T> when it consumes T values you write into (you can add a T but reads come back as Object).
Explanation
Collections.copy(dest, src) is the canonical example: src is <? extends T> (producer) and dest is <? super T> (consumer). Getting this right maximizes API flexibility — callers can pass List<Integer> where List<? extends Number> is expected.
Common mistakes
- Using <? extends T> for a collection you need to add to.
- Not being able to explain why Collections.copy uses both wildcards.