"Hei, Amigo!"

"Hei, Ellie!"

"I dag skal Rishi og jeg fortelle deg alt om generiske legemidler."

"Vent, jeg tror jeg allerede vet nesten alt."

"Nesten alt, men ikke alt."

"Virkelig? OK, jeg er klar til å lytte."

"Så la oss begynne."

"I Java er generiske klasser som har typeparametere."

"Når det gjelder hvorfor generika ble oppfunnet, se kommentarene i koden:"

Eksempel
ArrayList stringList = new ArrayList();
stringList.add("abc"); // Add a string to the list
stringList.add("abc"); // Add a string to the list
stringList.add( 1 ); // Add a number to the list

for(Object o: stringList)
{
 String s = (String) o; // There will be an exception here when we get to the integer
}

Slik løser du problemet ved å bruke Generics:

Eksempel
ArrayList<String> stringList = new ArrayList<String>();
stringList.add("abc"); // Add a string to the list
stringList.add("abc"); // Add a string to the list
stringList.add( 1 ); // There will be a compilation error here

for(Object o: stringList)
{
 String s = (String) o;
}

"Denne koden vil ganske enkelt ikke kompilere, og feilen forårsaket av å legge til feil datatype vil bli lagt merke til under kompileringen."

"Ja, jeg vet dette allerede."

"Ok, bra. Repetisjon er læringens mor."

"Men Javas skapere var litt late når de lagde generiske artikler. I stedet for å lage fullverdige typer med parametere, gled de inn en glatt optimalisering. I virkeligheten la de ikke til noen informasjon om typeparametere til generiske. I stedet ble alle magi oppstår under kompilering."

Kode med generikk
List<String> strings = new ArrayList<String>();
strings.add("abc");
strings.add("abc");
strings.add( 1); // Compilation error

for(String s: strings)
{
 System.out.println(s);
}
Hva skjer egentlig
List strings = new ArrayList();

strings.add((String)"abc");
strings.add((String)"abc");
strings.add((String) 1); // Compilation error

for(String s: strings)
{
 System.out.println(s);
}

"Det er glatt."

"Ja, men denne tilnærmingen har en bivirkning.  Ingen informasjon om typeparametere er lagret i en generisk klasse.  Denne tilnærmingen ble senere kjent som typesletting ."

"Med andre ord, hvis du har din egen klasse med typeparametere, kan du ikke bruke informasjon om dem inne i klassen."

Kode med generikk
class Zoo<T>
{
 ArrayList<T> pets = new ArrayList<T>();

 public T createAnimal()
 {
  T animal = new T();
  pets.add(animal)
  return animal;
 }
}
Hva skjer egentlig
class Zoo
{
 ArrayList pets = new ArrayList();

 public Object createAnimal()
 {
  Object animal = new ???();
  pets.add(animal)
  return animal;
 }
}

"Under kompilering erstattes alle parametertyper med Object. Og inne i klassen er det ingen informasjon om typen som sendes til den."

"Ja, jeg er enig, det er ikke det beste."

"Det er ikke så skummelt. Jeg skal fortelle deg senere hvordan du kan omgå dette problemet."

Men det er mer. Java lar deg spesifisere en overordnet type for typeparametere. Nøkkelordet extends brukes til dette. For eksempel:

Kode med generikk
class Zoo<T extends Cat>
{
 T cat;

 T getCat()
 {
  return cat;
 }

 void setCat (T cat)
 {
  this.cat = cat;
 }

 String getCatName()
 {
  return this.cat.getName();
 }
}
Hva skjer egentlig
class Zoo
{
 Cat cat;

 Cat getCat()
 {
  return cat;
 }

 void setCat(Cat cat)
 {
  this.cat = cat;
 }

 String getCatName()
 {
  return this.cat.getName();
 }
}

"Vær oppmerksom på to fakta:"

"For det første kan du ikke sende hvilken som helst type som parameter - du kan bare bestå en katt eller en klasse som arver katt."

"For det andre, inne i Zoo-klassen, kan variabler av type T nå kalle Cat-klassens metoder.  Kolonnen til høyre forklarer hvorfor (fordi Cat vil bli erstattet overalt hvor det er en T)"

"Ja. Hvis vi sier at Cat eller en underklasse av Cat blir bestått som typeargument, så er vi sikre på at type T alltid vil ha Cat-klassens metoder."

"Vel, det er smart."