"Hej, Amigo!"
"Hej, Ellie!"
"I dag skal Rishi og jeg fortælle dig alt om generiske lægemidler."
"Vent, jeg tror, jeg allerede ved næsten alt."
"Næsten alt, men ikke alt."
"Virkelig? OK, jeg er klar til at lytte."
"Så lad os begynde."
"I Java er generiske klasser, der har typeparametre."
"Med hensyn til hvorfor generika blev opfundet, se kommentarerne 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
}
Sådan løser du problemet ved hjælp af 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 kode vil simpelthen ikke kompilere, og fejlen forårsaget af tilføjelse af den forkerte datatype vil blive bemærket under kompileringen."
"Ja, det ved jeg allerede."
"Okay, godt. Gentagelse er læringens moder."
"Men Javas skabere var lidt dovne, da de lavede generika. I stedet for at lave fuldgyldige typer med parametre, gled de i en glat optimering. I virkeligheden tilføjede de ikke nogen information om typeparametre til generika. I stedet blev alle de magi opstå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 smart."
"Ja, men denne tilgang har en bivirkning. Ingen information om typeparametre er gemt i en generisk klasse. Denne tilgang blev senere kendt som typesletning ."
"Med andre ord, hvis du har din egen klasse med typeparametre, kan du ikke bruge information om dem inde 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 kompileringen bliver alle parametertyper erstattet med Object. Og inde i klassen er der ingen information om typen, der sendes til den."
"Ja, jeg er enig, det er ikke det bedste."
"Det er ikke så skræmmende. Jeg fortæller dig senere, hvordan du kan komme uden om dette problem."
Men der er mere. Java lader dig angive en overordnet type for typeparametre. Til dette bruges nøgleordet extends. 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();
}
}
"Bemærk to fakta:"
"For det første kan du ikke videregive en hvilken som helst type som parameter - du kan kun bestå en kat eller en klasse, der arver kat."
"For det andet, inde i Zoo-klassen, kan variabler af type T nu kalde Cat-klassens metoder. Kolonnen til højre forklarer hvorfor (fordi Cat vil blive erstattet overalt, hvor der er et T)"
"Ja. Hvis vi siger, at Cat eller en underklasse af Cat passeres som typeargumentet, så er vi sikre på, at type T altid vil have Cat-klassens metoder."
"Nå, det er smart."
GO TO FULL VERSION