
PECS stands for Producer-Extends, Consumer-Super. "For maximum flexibility, use wildcard types on input parameters that represent producers or consumers", and proposes the following mnemonic: Joshua Bloch gives the name Producers to objects you only read from and Consumers to those you only write to. If you call something that returns T in List, you don't get a String, but rather an Object. The latter is called contravariance, and you can only call methods that take String as an argument on List (for example, you can call add(String) or set(int, String)). Conversely, if you can only put items into the collection, it's okay to take a collection of Objects and put Strings into it: in Java there is List, a supertype of List. The key to understanding why this works is rather simple: if you can only take items from a collection, then using a collection of Strings and reading Objects from it is fine.

In other words, the wildcard with an extends-bound ( upper bound) makes the type covariant. In return for this limitation, you get the desired behavior: Collection is a subtype of Collection. This means that you can safely read E's from items (elements of this collection are instances of a subclass of E), but cannot write to it as you don't know what objects comply with that unknown subtype of E. The wildcard type argument ? extends E indicates that this method accepts a collection of objects of E or a subtype of E, not just E itself.
