"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:"
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:
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."
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);
}
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."
class Zoo<T>
{
ArrayList<T> pets = new ArrayList<T>();
public T createAnimal()
{
T animal = new T();
pets.add(animal)
return animal;
}
}
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:
class Zoo<T extends Cat>
{
T cat;
T getCat()
{
return cat;
}
void setCat (T cat)
{
this.cat = cat;
}
String getCatName()
{
return this.cat.getName();
}
}
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."
GO TO FULL VERSION