ConceptDifficulty: Advanced1 min

extends and super: Which Way the Values Are Allowed to Flow

A method that copies from one collection into another needs to accept more than one exact type on each side, and the two sides need opposite freedoms.

The two bounded wildcards, on what they accept and what you may do
WrittenAcceptsYou may readYou may add
List<? extends Invoice>A list of Invoice or of any subtypeAn InvoiceNothing
List<? super Invoice>A list of Invoice or of any supertypeAn ObjectAn Invoice

The restrictions follow from what the compiler can know. With ? extends Invoice it knows every element is at least an Invoice, so reading is safe — and it does not know which subtype, so nothing is safe to add. With ? super Invoice it knows the list can hold an Invoice, so adding one is safe — and it does not know what else is in there, so reading gives you Object.

java
void copy(List<? extends Invoice> from, List<? super Invoice> into) {
    for (Invoice invoice : from) {
        into.add(invoice);
    }
}

The mnemonic is producer extends, consumer super: the side you take values out of is extends, and the side you put values into is super.

So a wildcard on a parameter is a statement about direction. Use them on parameters where the direction is one-way, and leave a plain type parameter where a method both reads and writes.