Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Java

Java Generics में महारत हासिल करें: वे क्या हैं और कैसे उपयोग करें, एक स्पष्ट मार्गदर्शिका

Java Generics Java भाषा की सबसे महत्वपूर्ण विशेषताओं में से एक है। जेनेरिक्स के पीछे का विचार काफी सरल है, हालांकि यह कभी-कभी इसके साथ जुड़े सामान्य सिंटैक्स से बदलाव के कारण जटिल लग सकता है।

इस ट्यूटोरियल का उद्देश्य आपको जेनेरिक्स की इस उपयोगी अवधारणा को समझने में आसान तरीके से पेश करना है।

लेकिन जेनेरिक्स में गोता लगाने से पहले, आइए जानें कि Java जेनेरिक्स की आवश्यकता पहली जगह में क्यों पड़ी।

Java Generics का उद्देश्य

Java 5 में जेनेरिक्स की शुरुआत से पहले, आप नीचे दिए गए कोड स्निपेट को बिना किसी त्रुटि या चेतावनी के लिख और कंपाइल कर सकते थे:

List list = new ArrayList();
list.add("hey");
list.add(new Object());

आपको लिस्ट या किसी अन्य Java कलेक्शन में संग्रहीत डेटा के प्रकार की घोषणा किए बिना किसी भी प्रकार के मान जोड़ने की अनुमति थी। लेकिन जब आप लिस्ट से मान पुनः प्राप्त करते हैं, तो आपको इसे किसी निश्चित प्रकार में स्पष्ट रूप से कास्ट करना पड़ता है।

उपरोक्त लिस्ट के माध्यम से इटरेट करने पर विचार करें।

for (int i=0; i< list.size(); i++) {
    String value = (String) list.get(i); // i=1 पर ClassCastException
}

पहले डेटा प्रकार घोषित किए बिना लिस्ट बनाने की अनुमति देना, जैसा हमने किया, प्रोग्रामर्स को ऊपर जैसी गलतियां करने दे सकता है जो रनटाइम पर ClassCastExceptions फेंकती हैं।

जेनेरिक्स को प्रोग्रामर्स को ऐसी गलतियां करने से रोकने के लिए पेश किया गया था।

जेनेरिक्स के साथ, आप Java कलेक्शन बनाते समय स्पष्ट रूप से डेटा प्रकार घोषित कर सकते हैं जैसा कि निम्न उदाहरण दिखाता है।

नोट: आप अभी भी संग्रहीत डेटा प्रकार निर्दिष्ट किए बिना Java कलेक्शन ऑब्जेक्ट बना सकते हैं लेकिन इसकी अनुशंसा नहीं की जाती है।

List<String> stringList = new ArrayList<>();

अब, आप कंपाइल-टाइम त्रुटि फेंके बिना String प्रकार की लिस्ट में Integer को गलती से स्टोर नहीं कर सकते। यह सुनिश्चित करता है कि आपका प्रोग्राम रनटाइम त्रुटियों में न चले।

stringList.add(new Integer(4)); // कंपाइल टाइम Error

Java में जेनेरिक्स की शुरुआत का मुख्य उद्देश्य रनटाइम के दौरान ClassCastExceptions से बचना था।

Java Generics बनाना

आप Java क्लासेस और मेथड्स बनाने के लिए जेनेरिक्स का उपयोग कर सकते हैं। आइए प्रत्येक प्रकार के जेनेरिक्स बनाने के उदाहरण देखें।

जेनेरिक क्लास

जेनेरिक क्लास बनाते समय, क्लास के लिए टाइप पैरामीटर क्लास के नाम के अंत में एंगल <> ब्रैकेट्स के भीतर जोड़ा जाता है।

public class GenericClass<T> {
    private T item;
    public void setItem(T item) {
        this.item = item;
    }
    public T getItem() {
        return this.item;
    }
}

यहां, T डेटा प्रकार पैरामीटर है। T, N, और E Java कन्वेंशन के अनुसार डेटा प्रकार पैरामीटर्स के लिए उपयोग किए जाने वाले कुछ अक्षर हैं।

उपरोक्त उदाहरण में, आप GenericClass ऑब्जेक्ट बनाते समय एक विशिष्ट डेटा प्रकार पास कर सकते हैं।

public static void main(String[] args) {
    GenericClass<String> gc1 = new GenericClass<>();
    gc1.setItem("hello");
    String item1 = gc1.getItem(); // "hello"
    gc1.setItem(new Object()); // Error
    
    GenericClass<Integer> gc2 = new GenericClass<>();
    gc2.setItem(new Integer(1));
    Integer item2 = gc2.getItem(); // 1
    gc2.setItem("hello"); // Error
}

जेनेरिक क्लास ऑब्जेक्ट बनाते समय डेटा प्रकार पैरामीटर में प्रिमिटिव डेटा प्रकार पास नहीं कर सकते। केवल वे डेटा प्रकार जो Object प्रकार को एक्सटेंड करते हैं, टाइप पैरामीटर्स के रूप में पास किए जा सकते हैं।

उदाहरण के लिए:

GenericClass<float> gc3 = new GenericClass<>(); // Error

जेनेरिक मेथड्स

जेनेरिक मेथड्स बनाना जेनेरिक क्लासेस बनाने के समान पैटर्न का पालन करता है। आप जेनेरिक मेथड को जेनेरिक क्लास के साथ-साथ नॉन-जेनेरिक क्लास में भी लागू कर सकते हैं।

public class GenericMethodClass {
    public static <T> void printItems(T[] arr){
        for (int i=0; i< arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
    public static void main(String[] args) {
        String[] arr1 = {"Cat", "Dog", "Mouse"};
        Integer[] arr2 = {1, 2, 3};
        GenericMethodClass.printItems(arr1); // "Cat", "Dog", "Mouse"
        GenericMethodClass.printItems(arr2); // 1, 2, 3
    }
}

यहां, आप मेथड को पैरामीटराइज़ करने के लिए एक विशिष्ट प्रकार का ऐरे पास कर सकते हैं। जेनेरिक मेथड printItems() पास किए गए ऐरे के माध्यम से इटरेट करता है और आइटम्स को प्रिंट करता है जैसे एक सामान्य Java मेथड।

बाउंडेड टाइप पैरामीटर्स

अब तक, हमने ऊपर जो जेनेरिक क्लासेस और मेथड्स बनाए हैं, उन्हें प्रिमिटिव प्रकारों के अलावा किसी भी डेटा प्रकार के साथ पैरामीटराइज़ किया जा सकता है। लेकिन क्या होगा अगर हम उन डेटा प्रकारों को सीमित करना चाहें जिन्हें जेनेरिक्स में पास किया जा सकता है? यहीं बाउंडेड टाइप पैरामीटर्स काम आते हैं।

आप किसी अन्य डेटा प्रकार का सबक्लास होने को निर्दिष्ट करके जेनेरिक क्लास या मेथड द्वारा स्वीकृत डेटा प्रकारों को बांध सकते हैं।

उदाहरण के लिए:

// केवल List के सबक्लास स्वीकार करता है
public class UpperBoundedClass<T extends List>{
    // केवल List के सबक्लास स्वीकार करता है
    public <T extends List> void UpperBoundedMethod(T[] arr) {
    }
}

यहां, UpperBoundedClass और UpperBoundedMethod को केवल List डेटा प्रकार के सबटाइप्स का उपयोग करके पैरामीटराइज़ किया जा सकता है।

List डेटा प्रकार टाइप पैरामीटर के लिए अपर बाउंड के रूप में कार्य करता है। यदि आप किसी ऐसे डेटा प्रकार का उपयोग करने का प्रयास करते हैं जो List का सबटाइप नहीं है, तो यह कंपाइल-टाइम त्रुटि फेंकेगा।

बाउंड्स केवल क्लासेस तक सीमित नहीं हैं। आप इंटरफेसेस भी पास कर सकते हैं। इंटरफेस को एक्सटेंड करने का अर्थ है, इस मामले में, इंटरफेस को लागू करना।

एक पैरामीटर में कई बाउंड्स भी हो सकते हैं जैसा कि यह उदाहरण दिखाता है।

// केवल Mammal और Animal दोनों के सबक्लास स्वीकार करता है
public class MultipleBoundedClass<T extends Mammal & Animal>{
    // केवल Mammal और Animal दोनों के सबक्लास स्वीकार करता है
    public <T extends Mammal & Animal> void MultipleBoundedMethod(T[] arr){
    }
}

स्वीकार किया जाने वाला डेटा प्रकार Animal और Mammal दोनों क्लासेस का सबक्लास होना चाहिए। यदि इन बाउंड्स में से एक क्लास है, तो इसे बाउंड घोषणा में पहले आना चाहिए।

उपरोक्त उदाहरण में, यदि Mammal एक क्लास है और Animal एक इंटरफेस है, तो Mammal को ऊपर दिखाए अनुसार पहले आना चाहिए। अन्यथा, कोड कंपाइल-टाइम त्रुटि फेंकता है।

Java Generics वाइल्डकार्ड्स

वाइल्डकार्ड्स का उपयोग जेनेरिक प्रकारों के पैरामीटर्स को मेथड्स में पास करने के लिए किया जाता है। जेनेरिक मेथड के विपरीत, यहां जेनेरिक पैरामीटर मेथड द्वारा स्वीकृत पैरामीटर्स को पास किया जाता है, जो हमने ऊपर चर्चा किए गए डेटा प्रकार पैरामीटर से अलग है। एक वाइल्डकार्ड को ? सिंबल द्वारा दर्शाया जाता है।

public void printItems(List<?> list) {
    for (int i=0; i< list.size(); i++) {
        System.out.println(list.get(i));
    }
}

उपरोक्त printItems() मेथड पैरामीटर के रूप में किसी भी डेटा प्रकार की लिस्ट स्वीकार करता है। यह प्रोग्रामर्स को अलग-अलग डेटा प्रकारों की लिस्ट के लिए कोड दोहराने से रोकता है, जो जेनेरिक्स के बिना होता।

अपर बाउंडेड वाइल्डकार्ड्स

यदि हम मेथड द्वारा स्वीकृत लिस्ट में संग्रहीत डेटा प्रकारों को सीमित करना चाहते हैं, तो हम बाउंडेड वाइल्डकार्ड्स का उपयोग कर सकते हैं।

उदाहरण:

public void printSubTypes(List<? extends Color> list) {
    for (int i=0; i< list.size(); i++) {
        System.out.println(list.get(i));
    }
}

printSubTypes() मेथड केवल उन लिस्ट्स को स्वीकार करता है जो Color के सबटाइप्स स्टोर करती हैं। यह RedColor या BlueColor ऑब्जेक्ट्स की लिस्ट स्वीकार करता है, लेकिन Animal ऑब्जेक्ट्स की लिस्ट स्वीकार नहीं करता। क्योंकि Animal Color का सबटाइप नहीं है। यह अपर-बाउंडेड वाइल्डकार्ड का एक उदाहरण है।

लोअर बाउंडेड वाइल्डकार्ड्स

इसी तरह, यदि हमारे पास:

public void printSuperTypes(List<? super Dog> list) {
    for (int i=0; i< list.size(); i++) {
        System.out.println(list.get(i));
    }
}

तो, printSuperTypes() मेथड केवल उन लिस्ट्स को स्वीकार करता है जो Dog क्लास के सुपर टाइप्स स्टोर करती हैं। यह Mammal या Animal ऑब्जेक्ट्स की लिस्ट स्वीकार करेगा लेकिन LabDog ऑब्जेक्ट्स की लिस्ट नहीं क्योंकि LabDog Dog का सुपरक्लास नहीं है, बल्कि सबक्लास है। यह लोअर-बाउंडेड वाइल्डकार्ड का एक उदाहरण है।

निष्कर्ष

Java Generics अपनी शुरुआत के बाद से एक ऐसी विशेषता बन गई है जिसके बिना प्रोग्रामर्स नहीं रह सकते।

यह लोकप्रियता प्रोग्रामर्स के जीवन को आसान बनाने पर इसके प्रभाव के कारण है। कोडिंग गलतियों को रोकने के अलावा, जेनेरिक्स का उपयोग कोड को कम दोहराव वाला बनाता है। क्या आपने देखा कि यह कैसे क्लासेस और मेथड्स को सामान्यीकृत करता है ताकि अलग-अलग डेटा प्रकारों के लिए कोड दोहराना न पड़े?

जेनेरिक्स की अच्छी समझ भाषा में विशेषज्ञ बनने के लिए महत्वपूर्ण है। इसलिए, इस ट्यूटोरियल में सीखी गई बातों को व्यावहारिक कोड में लागू करना आगे बढ़ने का रास्ता है।

  1. गूगल मैप्स प्लस कोड्स खोजें: दुनिया में किसी भी स्थान का पता लगाने के लिए एक सरल गाइड गूगल मैप्स प्लस कोड्स खोजें: दुनिया में किसी भी स्थान का पता लगाने के लिए एक सरल गाइड

    शायद आपने Google मैप्स प्लस कोड्स के बारे में सुना है लेकिन उनके बारे में अधिक जानने का समय नहीं मिला। या शायद आपने Google मैप्स का उपयोग करते समय स्थानों के लिए प्लस कोड देखे हैं और सोचा कि वे क्या थे। यहां हम संक्षेप में बताएंगे कि प्लस कोड क्या हैं, उनका उद्देश्य, और आप उन्हें Google मैप्स पर कैस

  1. Google Assistant रूटीन मास्टर करें: जल्दी सेटअप करने का तरीका Google Assistant रूटीन मास्टर करें: जल्दी सेटअप करने का तरीका

    Google Assistant रूटीन विशिष्ट वाक्यांश बोलने पर Google Assistant द्वारा किए जाने वाले स्वचालित क्रियाओं का एक सेट है। आप छह तैयार Google Assistant रूटीन में से एक का उपयोग करके इस सुविधा को बहुत कम प्रयास से अभी उपयोग करना शुरू कर सकते हैं। लेकिन यदि आप रचनात्मक होना चाहते हैं, तो आप कस्टम Google A

  1. सिसइंटर्नल्स अनावरण: विंडोज प्रशासन के लिए शक्तिशाली उपकरण सिसइंटर्नल्स अनावरण: विंडोज प्रशासन के लिए शक्तिशाली उपकरण

    क्या आपने कभी चाहा है कि आपके विंडोज कंप्यूटर पर आपका पूरा नियंत्रण हो? लगभग किसी भी विंडोज प्रक्रिया या एप्लिकेशन के अंदर देखने में सक्षम होना ही नहीं, बल्कि उन फाइलों और रजिस्ट्री प्रविष्टियों को रीयल-टाइम में देखना भी अविश्वसनीय है जिन्हें आपके एप्लिकेशन एक्सेस कर रहे हैं। सबसे प्रतिष्ठित और शक्त