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