I've read a few topics about generic, but in this article's last paragraph Guidelines for Wildcard Use, this sentence "You can capture the wildcard and write elements that you've read from the list" really confuse me.
I have tested it in idea, here is the code:
class NaturalNumber {
private int i;
public NaturalNumber(int i) { this.i = i; }
// ...
}
class EvenNumber extends NaturalNumber {
public EvenNumber(int i) { super(i); }
// ...
}
// test method, ignore class
@Test
public void redisTest() {
List<EvenNumber> evenNumbers = new ArrayList<>();
evenNumbers.add(new EvenNumber(1));
List<? extends NaturalNumber> naturalNumbers = evenNumbers;
// idea compiler error, Required type:
//capture of ? extends NaturalNumber, Provided:
//capture of ? extends NaturalNumber
naturalNumbers.add(naturalNumbers.get(0));
}
why "naturalNumbers.add(naturalNumbers.get(0))" is not working, and how can I implement the "You can capture the wildcard and write elements that you've read from the list"
CodePudding user response:
why "naturalNumbers.add(naturalNumbers.get(0))" is not working
Because you are trying to write into a list of unknown subtype of NaturalNumber
. List<? extends NaturalNumber>
represents a list of NaturalNumber
or its sub-types such as EvenNumber
and OddNumber
. The compiler doesn't know the actual type.
how can I implement the "You can capture the wildcard and write elements that you've read from the list"
You can implement it like this:
private <T> void addNaturalNumber(List<T> naturalNumbers) {
naturalNumbers.add(naturalNumbers.get(0));
}
Here we say that the type variable T
has captured the wildcard.