The answer for this question tell that when a method takes a wildcard generic typ, the collection can be accessed or modified, but not both. (Kathy and Bert)
That's a fair first approximation, but we can say that:
You can not add
anything but null (Thanks Henry Wong) to a Collection<? extends Dog> because its add method takes an argument of ? extends Dog. Whenever you invoke a method, you must pass parameters that are of a subtype of the declared parameter type; but for the parameter type ? extends Dog, the compiler can never be sure the argument is of compatible type. However, you can of course modify the collection by calling clear() or remove(Object).
On the other hand, if you read from a Collection<? super Dog>, its iterator has return type ? super Dog. That is, it will return objects that are a subtype of some unknown supertype of Dog. But differently, the Collection could be a Collection<Object> containing only instances of
String. Therefore
so the only thing we know is that instances of Object are returned, i.e. the only type-correct way of iterating such a Collection is
but it is possible to read from a collection, you just don't know what types of objects you will get.
We can easily generalize that observation to: Given
and
we can not invoke any methods of G that are declared to take a parameter of type T, but we can invoke methods with return type T, and assign the result a variable of type Something.
On the other hand, for
we can invoke any methods of G that are declared to take parameters of type T, and we can invoke methods with return type T, but only assign the result to a variable of type Object.
To summarize, the restrictions on the use of wildcard types only depend on the form of the method declarations, not on what the methods do.