Java में Generics: क्यों आवश्यक हैं और कैसे उपयोग करें
Generics (सामान्यीकरण) Java भाषा की प्रमुख क्षमताओं में से एक है, जो J2SE 5.0 संस्करण में आई थी। ये क्लासेस, इंटरफेस और मेथड्स बनाने की अनुमति देते हैं जो विभिन्न डेटा प्रकारों के साथ काम करते हैं, साथ ही कम्पाइलेशन चरण में सख्त टाइपिंग बनाए रखते हैं। इस लेख में हम समझेंगे कि जेनेरिक्स की क्यों आवश्यकता है, उनका सही उपयोग कैसे करें और वे किन त्रुटियों से बचने में मदद करते हैं।
Java में Generics की आवश्यकता क्यों है?
सामान्यीकरण के आगमन से पहले, प्रोग्रामर टाइप कास्टिंग (casting) और Object के साथ काम करते थे। इससे दो मुख्य समस्याएँ उत्पन्न होती थीं:
- टाइप सुरक्षा का अभाव — कलेक्शन में किसी भी प्रकार की वस्तु जोड़ी जा सकती थी, और त्रुटि केवल रनटाइम पर दिखाई देती थी।
- स्पष्ट कास्टिंग की आवश्यकता — कलेक्शन से तत्व निकालते समय कास्ट करना पड़ता था, जिससे कोड अव्यवस्थित हो जाता था।
// Generics के बिना (Java 5 से पहले)List list = new ArrayList();list.add("स्ट्रिंग");list.add(123); // कम्पाइलेशन पर त्रुटि नहींString s = (String) list.get(0); // स्पष्ट रूप से कास्ट करना पड़ता है// Generics के साथList<String> list = new ArrayList<>();list.add("स्ट्रिंग");// list.add(123); // कम्पाइलेशन त्रुटि!String s = list.get(0); // कास्टिंग की आवश्यकता नहींGenerics के मुख्य लाभ:
- टाइप सुरक्षा — टाइप त्रुटियाँ कम्पाइलेशन चरण पर ही पकड़ी जाती हैं।
- स्पष्ट कास्टिंग का उन्मूलन — कोड साफ और अधिक पठनीय हो जाता है।
- कोड का पुन: उपयोग — एक ही कार्यान्वयन विभिन्न प्रकारों के साथ काम करता है।
सामान्यीकृत क्लासेस और मेथड्स बनाना
सामान्यीकृत क्लास
एक ऐसी क्लास बनाने के लिए जो किसी भी प्रकार के साथ काम करे, क्लास के नाम के बाद कोण कोष्ठक में टाइप पैरामीटर निर्दिष्ट करना पर्याप्त है:
public class Box<T> { private T content;
public void setContent(T content) { this.content = content; }
public T getContent() { return content; }
public static void main(String[] args) { Box<String> stringBox = new Box<>(); stringBox.setContent("नमस्ते, Java!"); System.out.println(stringBox.getContent());
Box<Integer> intBox = new Box<>(); intBox.setContent(42); System.out.println(intBox.getContent()); }}इस उदाहरण में, T टाइप पैरामीटर है। Box<String> ऑब्जेक्ट बनाते समय, T के सभी स्थानों पर String आ जाता है।
सामान्यीकृत मेथड
मेथड्स को भी पैरामीटराइज़ किया जा सकता है। टाइप पैरामीटर रिटर्न टाइप से पहले निर्दिष्ट किया जाता है:
public class Util { public static <T> void printArray(T[] array) { for (T element : array) { System.out.print(element + " "); } System.out.println(); }
public static void main(String[] args) { Integer[] intArray = {1, 2, 3, 4, 5}; String[] strArray = {"A", "B", "C"};
printArray(intArray); // 1 2 3 4 5 printArray(strArray); // A B C }}ध्यान दें: टाइप पैरामीटर <T> void से पहले आता है। सामान्यीकृत मेथड्स के लिए यह अनिवार्य है।
सीमित प्रकार (Bounded Type Parameters)
कभी-कभी यह सीमित करना आवश्यक होता है कि पैरामीटर के रूप में किन प्रकारों का उपयोग किया जा सकता है। इसके लिए extends और super कीवर्ड का उपयोग किया जाता है।
ऊपरी सीमा (extends)
प्रकार को ऊपर से सीमित करता है — केवल निर्दिष्ट क्लास या उसके उपवर्गों का उपयोग किया जा सकता है:
public class Calculator<T extends Number> { private T value;
public Calculator(T value) { this.value = value; }
public double square() { return va
```