"Hej! Jag ska fortsätta Ellies lektion om generika. Är du redo att lyssna?"

"Ja."

"Så låt oss börja."

"Det första du behöver veta är att en klasss metoder också kan ha sina egna typparametrar."

"Jag vet."

"Nej, jag menar specifikt deras egna typparametrar: "

Exempel
class Calculator
{
  T add(T a, T b); // Add
  T sub(T a, T b); // Subtract
  T mul(T a, T b); // Multiply
  T div(T a, T b); // Divide
}

"Dessa typparametrar hänför sig specifikt till metoderna. Klassen har inga parametrar. Du kan till och med förklara dessa metoder statiska och anropa dem utan ett objekt."

"Jag förstår. Poängen med typparametrarna i metoder är densamma som för klasser?"

"Ja. Men det är något nytt."

"Som du redan vet kan du använda ett jokertecken i typdeklarationen. Föreställ dig sedan följande situation:"

Exempel 1
public void doSomething(List<? extends MyClass> list)
{
 for(MyClass object : list)
 {
  System.out.println(object.getState()); // Everything works well here.
 }
}

"Men tänk om vi vill lägga till ett nytt föremål i samlingen:"

Exempel 2
public void doSomething(List<? extends MyClass> list)
{
 list.add(new MyClass()); // Error!
}

"Problemet är att i det allmänna fallet kan doSomething-metoden skickas till en List vars element inte är MyClass-objekt, utan snarare objekt av vilken underklass som helst av MyClass. Men du kan inte lägga till MyClass-objekt till en sådan lista!"

"Ah. Så, vad kan man göra åt det?"

"Ingenting. I den här situationen kan du inte göra någonting. Men detta gav Javas skapare något att tänka på. Och de kom på ett nytt nyckelord: super ."

"Syntaxen ser nästan likadan ut:"

List<? super MyClass> list

Men det finns en viktig skillnad mellan extends och super.

"«? förlänger T» betyder att klassen måste vara en ättling till T."

"«? super T» betyder att klassen måste vara en förfader till T."

"Holy moly. Så var används detta?"

"«? super T» används när en metod inbegriper tillägg till en samling av T-objekt. I det här fallet kan det vara en samling av T-objekt eller någon förfader till T."

"Ah. AT-objekt kan tilldelas en referensvariabel vars typ är någon av T:s förfäder"

"Ärligt talat, det här tillvägagångssättet används inte särskilt ofta. Dessutom har det en brist. Till exempel:"

Exempel
public void doSomething(List<? super MyClass> list)
{
 for(MyClass object : list) // Error!
 {
  System.out.println(object.getState());
 }
}
public void doSomething(List<? super MyClass> list)
{
 list.add(new MyClass()); // Everything works well here.
}

"Nu fungerar inte det första exemplet."

"Eftersom lista till och med kan vara en List<Object> (Objekt är MyClasss översta superklass), skriver vi i huvudsak följande ogiltiga kod:"

Exempel 1
List<Object> list;

for(MyClass object : list) // Error!
{
 System.out.println(object.getState());
}

"Jag förstår. Tack för den intressanta lektionen."

"Varsågod."