CodeGym /Java Blog /சீரற்ற /ஜாவாவில் உள்ள ஜெனரிக்ஸ்
John Squirrels
நிலை 41
San Francisco

ஜாவாவில் உள்ள ஜெனரிக்ஸ்

சீரற்ற குழுவில் வெளியிடப்பட்டது
வணக்கம்! நாம் ஜாவா ஜெனரிக்ஸ் பற்றி பேசப் போகிறோம். நீங்கள் நிறைய கற்றுக்கொள்வீர்கள் என்று நான் சொல்ல வேண்டும்! இந்தப் பாடம் மட்டுமின்றி, அடுத்த சில பாடங்களும், ஜெனரிக்ஸுக்கு அர்ப்பணிக்கப்படும். எனவே, நீங்கள் ஜெனரிக்ஸில் ஆர்வமாக இருந்தால், இன்றைய நாள் உங்களுக்கு அதிர்ஷ்டமான நாள்: ஜெனரிக்ஸின் அம்சங்களைப் பற்றி நீங்கள் நிறைய கற்றுக்கொள்வீர்கள். இல்லையென்றால், ராஜினாமா செய்துவிட்டு ஓய்வெடுங்கள்! :) இது மிக முக்கியமான தலைப்பு, நீங்கள் தெரிந்து கொள்ள வேண்டும். எளிமையானவற்றுடன் ஆரம்பிக்கலாம்: "என்ன" மற்றும் "ஏன்".

ஜாவா ஜெனரிக்ஸ் என்றால் என்ன?

ஜெனரிக்ஸ் என்பது அளவுருவைக் கொண்ட வகைகள். ஒரு பொதுவான வகையை உருவாக்கும் போது, ​​நீங்கள் ஒரு வகையை மட்டுமல்ல, அது வேலை செய்யும் தரவு வகையையும் குறிப்பிடுகிறீர்கள். மிகத் தெளிவான உதாரணம் ஏற்கனவே உங்கள் நினைவுக்கு வந்துள்ளது என்று நினைக்கிறேன்: வரிசைப்பட்டியல்! பொதுவாக ஒரு நிரலில் ஒன்றை உருவாக்குவது இப்படித்தான்:

import java.util.ArrayList;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       List<String> myList1 = new ArrayList<>();
       myList1.add("Test String 1");
       myList1.add("Test String 2");
   }
}
நீங்கள் யூகித்தபடி, இந்தப் பட்டியலின் ஒரு அம்சம் என்னவென்றால், எங்களால் எல்லாவற்றையும் அதில் நிரப்ப முடியாது: இது சரம் பொருள்களுடன் பிரத்தியேகமாக வேலை செய்கிறது. இப்போது ஜாவாவின் வரலாற்றில் ஒரு சிறிய திசைதிருப்பலை எடுத்து "ஏன்?" என்ற கேள்விக்கு பதிலளிக்க முயற்சிப்போம். இதைச் செய்ய, ArrayList வகுப்பின் எளிமையான பதிப்பை எழுதுவோம். உள் அணிவரிசையில் தரவைச் சேர்ப்பது மற்றும் தரவை மீட்டெடுப்பது எப்படி என்பதை மட்டுமே எங்கள் பட்டியலுக்குத் தெரியும்:

public class MyListClass {

   private Object[] data;
   private int count;

   public MyListClass() {
       this.data = new Object[10];
       this.count = 0;
   }

   public void add(Object o) {
       this.data[count] = o;
       count++;
   }

   public Object[] getData() {
       return data;
   }
}
எங்கள் பட்டியலில் முழு எண்களை மட்டுமே சேமிக்க வேண்டும் என்று வைத்துக்கொள்வோம் . நாங்கள் பொதுவான வகையைப் பயன்படுத்தவில்லை. add() முறையில் வெளிப்படையான "instanceof Integer " சரிபார்ப்பைச் சேர்க்க நாங்கள் விரும்பவில்லை . நாங்கள் அவ்வாறு செய்தால், எங்கள் முழு வகுப்பும் முழு எண்ணுக்கு மட்டுமே பொருத்தமானதாக இருக்கும் , மேலும் உலகில் உள்ள மற்ற எல்லா தரவு வகைகளுக்கும் இதே வகுப்பை எழுத வேண்டும்! நாங்கள் எங்கள் புரோகிராமர்களை நம்பியிருப்போம், மேலும் அவர்கள் நாங்கள் விரும்பாத எதையும் சேர்க்க மாட்டார்கள் என்பதை உறுதிப்படுத்த குறியீட்டில் ஒரு கருத்தை இடுங்கள்:

// Use this class ONLY with the Integer data type
public void add(Object o) {
   this.data[count] = o;
   count++;
}
புரோகிராமர்களில் ஒருவர் இந்தக் கருத்தைத் தவறவிட்டார் மற்றும் கவனக்குறைவாக எண்களின் பட்டியலில் பல சரங்களை வைத்து பின்னர் அவற்றின் தொகையைக் கணக்கிட்டார்:

public class Main {

   public static void main(String[] args) {

       MyListClass list = new MyListClass();
       list.add(100);
       list.add(200);
       list.add("Lolkek");
       list.add("Shalala");

       Integer sum1 = (Integer) list.getData()[0] + (Integer) list.getData()[1];
       System.out.println(sum1);

       Integer sum2 = (Integer) list.getData()[2] + (Integer) list.getData()[3];
       System.out.println(sum2);
   }
}
கன்சோல் வெளியீடு:

300 
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer 
      at Main.main (Main.java:14)
இந்த சூழ்நிலையின் மோசமான பகுதி என்ன? நிச்சயமாக புரோகிராமரின் கவனக்குறைவு அல்ல. மோசமான பகுதி என்னவென்றால், தவறான குறியீடு எங்கள் நிரலில் ஒரு முக்கியமான இடத்தில் முடிந்தது மற்றும் வெற்றிகரமாக தொகுக்கப்பட்டது. இப்போது நாம் குறியீட்டை எழுதும்போது பிழையை சந்திப்போம், ஆனால் சோதனையின் போது மட்டுமே (இது சிறந்த சூழ்நிலை!). வளர்ச்சியின் பிற்கால கட்டங்களில் பிழைகளை சரிசெய்வதற்கு அதிக செலவாகும் - பணம் மற்றும் நேரத்தின் அடிப்படையில். இங்குதான் ஜெனரிக்ஸ் நமக்குப் பலனளிக்கிறது: ஒரு பொதுவான வகுப்பு துரதிர்ஷ்டவசமான புரோகிராமரை உடனடியாக பிழையைக் கண்டறிய அனுமதிக்கிறது. நிரல் வெறுமனே தொகுக்கப்படாது!

import java.util.ArrayList;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       List<Integer> myList1 = new ArrayList<>();
      
       myList1.add(100);
       myList1.add(100);
       myList1.add ("Lolkek"); // Error!
       myList1.add("Shalala"); // Error!
   }
}
புரோகிராமர் உடனடியாக தனது தவறை உணர்ந்து, உடனடியாக குணமடைவார். அப்படியானால், இந்த வகையான பிழையைப் பார்க்க, நாங்கள் எங்கள் சொந்த பட்டியல் வகுப்பை உருவாக்க வேண்டியதில்லை . சாதாரண வரிசைப்பட்டியலில் இருந்து கோண அடைப்புக்குறிகளை அகற்றி ( <Integer> ) தட்டச்சு செய்யவும்!

import java.util.ArrayList;
import java.util.List;

public class Main {

   public static void main(String[] args) {

      List list = new ArrayList();

      list.add(100);
      list.add(200);
      list.add("Lolkek");
      list.add("Shalala");

       System.out.println((Integer) list.get(0) + (Integer) list.get(1));
       System.out.println((Integer) list.get(2) + (Integer) list.get(3));
   }
}
கன்சோல் வெளியீடு:

300 
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer 
     at Main.main(Main.java:16)
வேறு வார்த்தைகளில் கூறுவதானால், ஜாவாவின் "நேட்டிவ்" பொறிமுறைகளைப் பயன்படுத்தினாலும், நாம் இதுபோன்ற தவறுகளைச் செய்து பாதுகாப்பற்ற சேகரிப்பை உருவாக்கலாம். இருப்பினும், இந்த குறியீட்டை IDE இல் ஒட்டினால், நமக்கு ஒரு எச்சரிக்கை வரும்: "ஜாவா.util.List இன் மூல வகையின் உறுப்பினராக(E) சேர்ப்பதற்கான தேர்வு செய்யப்படாத அழைப்பு" ஒரு பொருளைச் சேர்க்கும்போது ஏதோ தவறு நேரலாம் என்று கூறப்படுகிறோம். பொதுவான வகை இல்லாத சேகரிப்புக்கு. ஆனால் "மூல வகை" என்ற சொற்றொடர் என்ன அர்த்தம்? மூல வகை என்பது ஒரு பொதுவான வகுப்பாகும், அதன் வகை அகற்றப்பட்டது. வேறு வார்த்தைகளில் கூறுவதானால், பட்டியல் myList1 ஒரு மூல வகை . ஒரு மூல வகைக்கு நேர்மாறானது ஒரு பொதுவான வகை - அளவுருப்படுத்தப்பட்ட வகை(களின்) குறிப்பைக் கொண்ட ஒரு பொதுவான வகுப்பு . எடுத்துக்காட்டாக, பட்டியல்<ஸ்ட்ரிங்> myList1. மொழி ஏன் மூல வகைகளைப் பயன்படுத்த அனுமதிக்கிறது என்று நீங்கள் கேட்கலாம் ? காரணம் எளிமையானது. பொருந்தக்கூடிய சிக்கல்களை உருவாக்குவதைத் தவிர்ப்பதற்காக ஜாவாவின் படைப்பாளிகள் மொழியில் மூல வகைகளுக்கான ஆதரவை விட்டுவிட்டனர். ஜாவா 5.0 வெளியிடப்பட்ட நேரத்தில் (ஜெனரிக்ஸ் முதலில் இந்த பதிப்பில் தோன்றியது), நிறைய குறியீடுகள் ஏற்கனவே மூல வகைகளைப் பயன்படுத்தி எழுதப்பட்டிருந்தன . இதன் விளைவாக, இந்த வழிமுறை இன்றும் ஆதரிக்கப்படுகிறது. பாடங்களில் ஜோசுவா ப்ளாச்சின் கிளாசிக் புத்தகமான "எஃபெக்டிவ் ஜாவா" பற்றி மீண்டும் மீண்டும் குறிப்பிட்டுள்ளோம். மொழியின் படைப்பாளிகளில் ஒருவராக, அவர் தனது புத்தகத்தில் மூல வகைகளையும் பொதுவான வகைகளையும் தவிர்க்கவில்லை .ஜாவாவில் ஜெனரிக்ஸ் என்றால் என்ன?  - 2புத்தகத்தின் 23வது அத்தியாயம் மிகவும் சொற்பொழிவான தலைப்பு: "புதிய குறியீட்டில் மூல வகைகளைப் பயன்படுத்த வேண்டாம்" இதைத்தான் நீங்கள் நினைவில் கொள்ள வேண்டும். பொதுவான வகுப்புகளைப் பயன்படுத்தும் போது, ​​பொதுவான வகையை ஒருபோதும் மூல வகையாக மாற்ற வேண்டாம் .

பொதுவான முறைகள்

பொதுவான முறைகள் என்று அழைக்கப்படுவதை உருவாக்குவதன் மூலம் தனிப்பட்ட முறைகளை அளவுருவாக மாற்ற ஜாவா உங்களை அனுமதிக்கிறது. இத்தகைய முறைகள் எவ்வாறு பயனுள்ளதாக இருக்கும்? எல்லாவற்றிற்கும் மேலாக, பல்வேறு வகையான முறை அளவுருக்களுடன் பணிபுரிய உங்களை அனுமதிக்கும் வகையில் அவை உதவியாக இருக்கும். ஒரே தர்க்கத்தை வெவ்வேறு வகைகளுக்குப் பாதுகாப்பாகப் பயன்படுத்தினால், பொதுவான முறை ஒரு சிறந்த தீர்வாக இருக்கும். இதை மிக எளிமையான உதாரணமாகக் கருதுங்கள்: myList1 எனப்படும் சில பட்டியல் நம்மிடம் இருப்பதாக வைத்துக்கொள்வோம் . பட்டியலிலிருந்து எல்லா மதிப்புகளையும் அகற்றிவிட்டு அனைத்து காலி இடங்களையும் புதிய மதிப்புகளால் நிரப்ப விரும்புகிறோம். பொதுவான முறையில் எங்கள் வகுப்பு எப்படி இருக்கிறது என்பது இங்கே:

public class TestClass {

   public static <T> void fill(List<T> list, T val) {
       for (int i = 0; i < list.size(); i++)
           list.set(i, val);
   }

   public static void main(String[] args) {

       List<String> strings = new ArrayList<>();
       strings.add("Old String 1");
       strings.add("Old String 2");
       strings.add("Old String 3");

       fill(strings, "New String");

       System.out.println(strings);

       List<Integer> numbers = new ArrayList<>();
       numbers.add(1);
       numbers.add(2);
       numbers.add(3);

       fill(numbers, 888);
       System.out.println(numbers);
   }
}
தொடரியல் மீது கவனம் செலுத்துங்கள். இது சற்று அசாதாரணமாக தெரிகிறது:

public static <T> void fill(List<T> list, T val)
திரும்பும் வகைக்கு முன் <T> என்று எழுதுகிறோம். நாங்கள் ஒரு பொதுவான முறையைக் கையாளுகிறோம் என்பதை இது குறிக்கிறது. இந்த வழக்கில், முறை 2 அளவுருக்களை உள்ளீடாக ஏற்றுக்கொள்கிறது: T பொருள்களின் பட்டியல் மற்றும் மற்றொரு தனி T பொருள். <T> ஐப் பயன்படுத்துவதன் மூலம், முறையின் அளவுரு வகைகளை நாம் அளவுருவாக்குகிறோம்: சரங்கள் மற்றும் முழு எண்ணின் பட்டியலில் எங்களால் அனுப்ப முடியாது. சரங்கள் மற்றும் ஒரு சரங்களின் பட்டியல், முழு எண்கள் மற்றும் ஒரு முழு எண், எங்கள் சொந்த பூனை பொருள்களின் பட்டியல் மற்றும் மற்றொரு பூனை பொருளின் பட்டியல் - இதைத்தான் நாம் செய்ய வேண்டும். பல்வேறு வகையான தரவுகளுடன் வேலை செய்ய நிரப்பு() முறையை எவ்வாறு எளிதாகப் பயன்படுத்தலாம் என்பதை முதன்மை () முறை விளக்குகிறது . முதலில், சரங்களின் பட்டியலையும், ஒரு சரத்தையும் உள்ளீடாகவும், பின்னர் முழு எண்கள் மற்றும் ஒரு முழு எண்ணையும் கொண்டு முறையைப் பயன்படுத்துகிறோம். கன்சோல் வெளியீடு:

[New String, New String, New String] [888, 888, 888]
எங்களிடம் பொதுவான முறைகள் இல்லை மற்றும் 30 வெவ்வேறு வகுப்புகளுக்கு நிரப்பு() முறையின் தர்க்கம் தேவையா என்று கற்பனை செய்து பாருங்கள். வெவ்வேறு தரவு வகைகளுக்கு ஒரே முறையை 30 முறை எழுத வேண்டும்! ஆனால் பொதுவான முறைகளுக்கு நன்றி, நாங்கள் எங்கள் குறியீட்டை மீண்டும் பயன்படுத்தலாம்! :)

பொதுவான வகுப்புகள்

நிலையான ஜாவா நூலகங்களில் வழங்கப்படும் பொதுவான வகுப்புகளுக்கு நீங்கள் மட்டுப்படுத்தப்படவில்லை - நீங்கள் சொந்தமாக உருவாக்கலாம்! இங்கே ஒரு எளிய உதாரணம்:

public class Box<T> {

   private T t;

   public void set(T t) {
       this.t = t;
   }

   public T get() {
       return t;
   }

   public static void main(String[] args) {

       Box<String> stringBox = new Box<>();

       stringBox.set("Old String");
       System.out.println(stringBox.get());
       stringBox.set("New String");

       System.out.println(stringBox.get());
      
       stringBox.set(12345); // Compilation error!
   }
}
எங்கள் பெட்டி<T> வகுப்பு ஒரு பொதுவான வகுப்பு. உருவாக்கும் போது தரவு வகையை ( <T> ) ஒதுக்கினால் , அதில் மற்ற வகை பொருட்களை வைக்க முடியாது. இதை எடுத்துக்காட்டில் காணலாம். எங்கள் பொருளை உருவாக்கும் போது, ​​​​அது சரங்களுடன் வேலை செய்யும் என்று நாங்கள் சுட்டிக்காட்டினோம்:

Box<String> stringBox = new Box<>();
மேலும் குறியீட்டின் கடைசி வரியில், 12345 என்ற எண்ணை பெட்டிக்குள் வைக்க முயலும்போது, ​​தொகுத்தல் பிழை வருகிறது! இது மிகவும் எளிதானது! நாங்கள் எங்கள் சொந்த பொதுவான வகுப்பை உருவாக்கியுள்ளோம்! :) இத்துடன் இன்றைய பாடம் முடிவடைகிறது. ஆனால் நாங்கள் ஜெனரிக்ஸுக்கு விடைபெறவில்லை! அடுத்த பாடங்களில், இன்னும் மேம்பட்ட அம்சங்களைப் பற்றி பேசுவோம், எனவே நீங்கள் விட்டுவிடாதீர்கள்! ) நீங்கள் கற்றுக்கொண்டதை வலுப்படுத்த, எங்கள் ஜாவா பாடத்திலிருந்து வீடியோ பாடத்தைப் பார்க்க பரிந்துரைக்கிறோம்
உங்கள் படிப்பில் சிறந்த வெற்றி! :)
கருத்துக்கள்
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION