"హాయ్, అమిగో!"

"హాయ్, ఎల్లీ!"

"ఈరోజు, రిషి మరియు నేను మీకు జెనరిక్స్ గురించి చెప్పబోతున్నాం."

"ఆగండి, నేను ఇప్పటికే దాదాపు ప్రతిదీ తెలుసు అనుకుంటున్నాను."

"దాదాపు ప్రతిదీ, కానీ ప్రతిదీ కాదు."

"నిజంగానా? సరే, నేను వినడానికి సిద్ధంగా ఉన్నాను."

"అప్పుడు ప్రారంభిద్దాం."

"జావాలో, జెనరిక్స్ అనేది టైప్ పారామితులను కలిగి ఉండే తరగతులు."

"జనరిక్‌లు ఎందుకు కనుగొనబడ్డాయి అనే దాని గురించి, కోడ్‌లోని వ్యాఖ్యలను చూడండి:"

ఉదాహరణ
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
}

జెనరిక్స్ ఉపయోగించి సమస్యను ఎలా పరిష్కరించాలి:

ఉదాహరణ
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;
}

"ఈ కోడ్ కంపైల్ చేయదు మరియు తప్పు డేటా రకాన్ని జోడించడం వల్ల ఏర్పడే లోపం సంకలనం సమయంలో గుర్తించబడుతుంది."

"అవును, ఇది నాకు ముందే తెలుసు."

"సరే, బాగుంది. పునరావృతం అనేది నేర్చుకునే తల్లి."

"కానీ జావా సృష్టికర్తలు జెనరిక్స్‌ను రూపొందించినప్పుడు కొంచెం బద్ధకంగా ఉన్నారు. పారామీటర్‌లతో పూర్తి స్థాయి రకాలను తయారు చేయడానికి బదులుగా, వారు స్లిక్ ఆప్టిమైజేషన్‌లో జారిపోయారు. వాస్తవానికి, వారు టైప్ పారామీటర్‌ల గురించి ఎలాంటి సమాచారాన్ని జెనరిక్స్‌కు జోడించలేదు. బదులుగా, అన్ని సంకలనం సమయంలో మేజిక్ జరుగుతుంది."

జెనరిక్స్‌తో కోడ్
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);
}

"అది మృదువుగా ఉంది."

"అవును, కానీ ఈ విధానం సైడ్ ఎఫెక్ట్‌ను కలిగి ఉంది.  టైప్ పారామీటర్‌ల గురించి ఎటువంటి సమాచారం సాధారణ తరగతిలో నిల్వ చేయబడదు. ఈ విధానం తర్వాత టైప్ ఎరేజర్‌గా  పిలువబడింది ."

"మరో మాటలో చెప్పాలంటే, మీరు టైప్ పారామితులతో మీ స్వంత తరగతిని కలిగి ఉంటే, మీరు వాటి గురించిన సమాచారాన్ని తరగతి లోపల ఉపయోగించలేరు."

జెనరిక్స్‌తో కోడ్
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;
 }
}

"సంకలనం సమయంలో, అన్ని పారామీటర్ రకాలు ఆబ్జెక్ట్‌తో భర్తీ చేయబడతాయి. మరియు తరగతి లోపల దానికి పంపబడిన రకం గురించి సమాచారం లేదు."

"అవును, నేను అంగీకరిస్తున్నాను, అది ఉత్తమమైనది కాదు."

"అంత భయానకంగా లేదు. ఈ సమస్యను ఎలా అధిగమించాలో తర్వాత చెబుతాను."

కానీ ఇంకా ఉంది. టైప్ పారామితుల కోసం పేరెంట్ రకాన్ని పేర్కొనడానికి జావా మిమ్మల్ని అనుమతిస్తుంది. దీని కోసం విస్తారిత కీవర్డ్ ఉపయోగించబడుతుంది. ఉదాహరణకి:

జెనరిక్స్‌తో కోడ్
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();
 }
}

"రెండు వాస్తవాలను గమనించండి:"

"మొదట, మీరు ఏ రకాన్ని పారామీటర్‌గా పాస్ చేయలేరు — మీరు క్యాట్ లేదా క్యాట్‌ను వారసత్వంగా పొందే తరగతిని మాత్రమే పాస్ చేయగలరు."

"రెండవది, జూ క్లాస్ లోపల, టైప్ T యొక్క వేరియబుల్స్ ఇప్పుడు క్యాట్ క్లాస్ పద్ధతులను పిలుస్తాయి.  కుడి వైపున ఉన్న కాలమ్ ఎందుకు వివరిస్తుంది (ఎందుకంటే T ఉన్న ప్రతిచోటా పిల్లి ప్రత్యామ్నాయంగా ఉంటుంది)"

"అవును. మేము క్యాట్ లేదా క్యాట్ యొక్క సబ్‌క్లాస్ టైప్ ఆర్గ్యుమెంట్‌గా పాస్ చేయబడిందని చెబితే, టైప్ T ఎల్లప్పుడూ క్యాట్ క్లాస్ పద్ధతులను కలిగి ఉంటుందని మేము ఖచ్చితంగా అనుకుంటున్నాము."

"సరే, అది తెలివైనది."