"Nå til et nytt, interessant emne: jokertegn."

"I hovedsak er dette noe sånt som et «*»-mønster som matcher hva som helst."

"Men la oss starte fra begynnelsen."

"Se for deg at du har en Warrior-klasse og en metode som bestemmer hvilken av to krigere som er sterkest. Slik kan dette se ut:"

Eksempel 1
class WarriorManager
{
 public static boolean fight(Warrior w1, Warrior w2)
 {
  return w1.power > w2.power;
 }
}
Eksempel på metodekall
MagicWarrior mag = new MagicWarrior();
ArcherWarrior archer = new ArcherWarrior();

boolean isMagicCooler = WarriorManager.fight(mag, archer);

"MagicWarrior og ArcherWarrior arver begge Warrior. ."

"Det er lite forenklet, men for et eksempel vil det gjøre det."

"OK."

"Anta nå at du har bestemt deg for å lage en lignende metode for situasjonen der flere krigere har sluttet seg til kampen."

Eksempel 1
class WarriorManager
{
 public static boolean fight(Warrior w1, Warrior w2)
 {
  return w1.power > w2.power;
 }

 public static boolean fight(List<Warrior> w1, List<Warrior> w2)
 {
  return 
 }
}
Eksempel på metodekall
ArrayList<MagicWarrior> magi = new ArrayList<MagicWarrior>();
for(int i = 0; i < 10; i++)
 magi.add(new MagicWarrior());

ArrayList<ArcherWarrior> archers = new ArrayList<ArcherWarrior>();
for(int i = 0; i < 10; i++)
 archers.add(new ArcherWarrior());

boolean isMagicCooler = WarriorManager.fight(magi, archers); // Compilation error!

"Men her støter du på en kompileringsfeil og lurer på hva som kan være galt."

"Tingen er at MagicWarrior arver Warrior , og MagicWarrior-objekter kan sendes til kamp(Warrior, Warrior)-metoden."

"Men List<MagicWarior> arver ikke List<Warrior> . Så du kan ikke sende den der!"

"Hva mener du med at den ikke arver den?"

"Jeg mener dette: den ene er en liste og den andre er en liste, men de har typeparametere."

"Du har rett. Jeg la på en eller annen måte ikke merke til det med en gang. Så, er det allerede en løsning på dette problemet?"

"Jepp. Du må bruke en mer kompleks struktur. Slik ser det ut:"

Eksempel 1
class WarriorManager
{
 public static boolean fight(Warrior w1, Warrior w2)
 {
  return w1.power > w2.power;
 }

 public static boolean fight(List<? extends Warrior> w1, List<? extends Warrior> w2)
 {
  return …
 }
}

«? forlenger Warrior»-delen betyr «enhver type som arver Warrior»»

"Med andre ord, nå kan du sende en Liste<MagicWarrior> og en Liste<ArcherWarrior>, og alt vil fungere."

"Det er så fantastisk. Jo færre slike problemer, jo bedre."

— Det er sånn jeg føler det også.

"Men hva om jeg ikke trenger noe som arver Warrior? Hva om jeg vil kunne sende en liste med en hvilken som helst typeparameter til metoden? Er det tillatt?"

"Ja, det er to former for notasjon for å gjøre det:"

List<? extends Object>
List<?>

"De betyr begge det samme, så den andre versjonen brukes vanligvis."

"Det var alt for i dag."

"Takk, Ellie. Jeg har virkelig lært mye i dag."