I've been messing around and I weren't capable of figure out.
In this question:
In the answer is sayd that if we uncomment line 5, we have compiler error at lines 7, 8 and 9, because the compiler doesn't know this instantiation generic type(runtime type), not bind to any value to its gereric criteria.
And If we uncommment line 6, we have compiler error at line 7. In this case, the type can bind any value that is Aliphatic or a subtype of it.
But this answer still leave me some doubts about that, and the book it is also ambiguous. Is there any other explanation?
I think I found a great summary of the use of Wildcard that make the whole thing simple.
Variables as providing one of two functions:
An "In" Variable, it is a kind of read-only but not strictly, you can write or remove elements in some ways. Imagine a copy method with two arguments: copy(src, dest). The src argument provides the data to be copied, so it is the "in" parameter.
An "Out" Variable, holds data for use elsewhere. In the copy example, copy(src, dest), the dest argument accepts data, so it is the "out" parameter.
An "in" variable is defined with an upper bounded wildcard, using the extends keyword.
An "out" variable is defined with a lower bounded wildcard, using the super keyword.
In the case where the "in" variable can be accessed using methods defined in the Object class, use an unbounded wildcard.
In the case where the code needs to access the variable as both an "in" and an "out" variable, do not use a wildcard.
Consider the following code:
Because List<EvenNumber> is a subtype of List<? extends NaturalNumber>, you can assign le to ln. But you cannot use ln to add a natural number to a list of even numbers. The following operations on the list are possible:
You can add null.
You can invoke clear.
You can get the iterator and invoke remove.
You can capture the wildcard and write elements that you've read from the list.