No, it's not read-only... even though that is typically the intention.
Given a List<? extends Number>
object, the compiler converts its type to List<X>
where X is an unknown subtype of Number. Therefore, the object does have an add(X)
method. We can call the method with an X
argument... for example, null
.
And since get()
returns X
, we could also call add()
with a value from get()
.... Directly invoking list.add(list.get(i))
won't work, even though it makes sense. We will need a little helper.
The classic example is Collections.reverse(List<? extends Object> list)
. This method will modify the list
, despite the wildcard.
You can also call mutating methods like clear()
, of course, on any list.
That being said, wildcard is indeed mainly for use-site variance, and most often, it conveys the intention from the API designer of whether a type-parameter is intended for in or out. For example, by declaring List<? super/extends Foo>
, the API expresses that it intends to inject T in to, or, get T out of, the list.
It is a misconception that wildcard makes read/write-only. But this misconception works in most use cases. And the more people having this misconception, the more it becomes a convention...
see my article on wildcard - http://bayou.io/draft/Capturing_Wildcards.html