"Hej, Amigo!"

"Hej Ellie!"

"Idag ska Rishi och jag berätta allt om generika."

"Vänta, jag tror att jag redan vet nästan allt."

"Nästan allt, men inte allt."

"Verkligen? OK, jag är redo att lyssna."

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

"I Java är generika klasser som har typparametrar."

"Angående varför generika uppfanns, se kommentarerna i koden:"

Exempel
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å här löser du problemet med Generics:

Exempel
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;
}

"Den här koden kommer helt enkelt inte att kompilera, och felet som orsakas av att fel datatyp läggs till kommer att märkas under kompileringen."

"Ja, jag vet redan det här."

"Okej, bra. Upprepning är lärandets moder."

"Men Javas skapare var lite lata när de skapade generika. Istället för att göra fullfjädrade typer med parametrar, halkade de in en smart optimering. I verkligheten lade de inte till någon information om typparametrar till generika. Istället har alla de magi uppstår under kompilering."

Kod med generika
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);
}
Vad händer egentligen
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 är tjusigt."

"Ja, men det här tillvägagångssättet har en bieffekt.  Ingen information om typparametrar lagras i en generisk klass.  Detta tillvägagångssätt blev senare känt som typradering ."

"Med andra ord, om du har en egen klass med typparametrar kan du inte använda information om dem i klassen."

Kod med generika
class Zoo<T>
{
 ArrayList<T> pets = new ArrayList<T>();

 public T createAnimal()
 {
  T animal = new T();
  pets.add(animal)
  return animal;
 }
}
Vad händer egentligen
class Zoo
{
 ArrayList pets = new ArrayList();

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

"Under kompileringen ersätts alla parametertyper med Object. Och inuti klassen finns ingen information om typen som skickas till den."

"Ja, jag håller med, det är inte det bästa."

"Det är inte så läskigt. Jag ska berätta för dig senare hur du kan komma runt det här problemet."

Men det finns mer. Java låter dig ange en överordnad typ för typparametrar. Nyckelordet extends används för detta. Till exempel:

Kod med generika
class Zoo<T extends Cat>
{
 T cat;

 T getCat()
 {
  return cat;
 }

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

 String getCatName()
 {
  return this.cat.getName();
 }
}
Vad händer egentligen
class Zoo
{
 Cat cat;

 Cat getCat()
 {
  return cat;
 }

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

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

"Notera två fakta:"

"För det första kan du inte skicka vilken typ som helst som en parameter - du kan bara skicka en katt eller en klass som ärver Cat."

"För det andra, inuti Zoo-klassen, kan variabler av typ T nu anropa Cat-klassens metoder.  Kolumnen till höger förklarar varför (eftersom Cat kommer att ersättas överallt där det finns ett T)"

"Ja. Om vi ​​säger att Cat eller en underklass av Cat skickas som typargument, så är vi säkra på att typ T alltid kommer att ha Cat-klassens metoder."

"Tja, det är smart."