Java में Generics: क्यों ज़रूरी हैं और व्यवहार में कैसे उपयोग करें

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

परिचय: वह समस्या जिसे Generics हल करते हैं

\n

कल्पना करें कि आप संख्याओं की सूची को सॉर्ट करने के लिए एक मेथड लिख रहे हैं। आप इसे Integer के लिए लिखते हैं, और एक सप्ताह बाद आपको String की सूची को सॉर्ट करने की आवश्यकता होती है। आपको एक नया मेथड बनाना होगा या Object का उपयोग करना होगा और लगातार टाइप कास्टिंग करनी होगी। यह असुविधाजनक, असुरक्षित है और रनटाइम के दौरान त्रुटियों की ओर ले जाता है।

\n

Java में Generics (जेनेरिक्स) इसी समस्या को हल करते हैं। वे क्लासेस, इंटरफेसेस और मेथड्स बनाने की अनुमति देते हैं जो विभिन्न डेटा प्रकारों के साथ काम करते हैं, लेकिन कंपाइलेशन चरण में सख्त टाइपिंग बनाए रखते हैं। जेनेरिक्स के बिना, आधुनिक Java बहुत कम सुविधाजनक और सुरक्षित होता।

\n

इस लेख में, हम समझेंगे कि Generics क्यों ज़रूरी हैं, वे कैसे काम करते हैं, और सबसे महत्वपूर्ण बात, वास्तविक उदाहरणों पर उन्हें कैसे लागू करें।

\n\n

1. Generics की मूल बातें: यह क्या है और कैसे काम करता है

\n

1.1. "रॉ" प्रकारों (raw types) की समस्या

\n

Java 5 (2004) से पहले, डेवलपर्स बिना प्रकार निर्दिष्ट किए कलेक्शन का उपयोग करते थे:

\n
List list = new ArrayList();\nlist.add("Hello");\nlist.add(123);\n// प्राप्त करते समय याद रखना होता है कि कौन सा प्रकार है\nString text = (String) list.get(0); // ठीक है\nInteger num = (Integer) list.get(1); // ठीक है\n// लेकिन अगर गलती हो जाए — runtime में ClassCastException\nString error = (String) list.get(1); // त्रुटि!
\n

ऐसा कोड खतरनाक है: त्रुटि केवल प्रोग्राम चलाने पर ही पता चलती है।

\n\n

1.2. Generics कैसे काम करते हैं

\n

Generics आपको कोण कोष्ठक <T> में सीधे उस डेटा प्रकार को निर्दिष्ट करने की अनुमति देते हैं जिसके साथ क्लास या मेथड काम करेगा। कंपाइलर कंपाइलेशन चरण में प्रकारों की जाँच करता है और स्वचालित रूप से सही कास्टिंग सम्मिलित करता है।

\n

मूल सिंटैक्स:

\n
// जेनेरिक क्लास की घोषणा\npublic class Box<T> {\n    private T content;\n    \n    public void setContent(T content) {\n        this.content = content;\n    }\n    \n    public T getContent() {\n        return content;\n    }\n}\n\n// उपयोग\nBox<String> stringBox = new Box<>(); // <> — डायमंड ऑपरेटर (Java 7+)\nstringBox.setContent("नमस्ते");\nString text = stringBox.getContent(); // बिना कास्टिंग के!\n\nBox<Integer> intBox = new Box<>();\nintBox.setContent(42);\nint number = intBox.getContent(); // बिना कास्टिंग के!\n\n// stringBox.setContent(123); // कंपाइलेशन त्रुटि!
\n\n

1.3. व्यवहार में लाभ

\n
    \n
  • प्रकार सुरक्षा: त्रुटियाँ runtime के बजाय कंपाइलेशन चरण में पकड़ी जाती हैं।
  • \n
  • स्पष्ट कास्टिंग का उन्मूलन: कोड साफ और अधिक पठनीय हो जाता है।
  • \n
  • कोड का पुन: उपयोग: एक क्लास/मेथड किसी भी प्रकार के साथ काम करता है।
  • \n
\n\n

2. व्यवहार में Generics: क्लासेस, मेथड्स और इंटरफेसेस

\n

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

\n

सबसे सामान्य मामला कलेक्शन है। लेकिन आप अपनी खुद की जेनेरिक क्लासेस बना सकते हैं:

\n
public class Pair<K, V> {\n    private K key;\n    private V value;\n    \n    public Pair(K key, V value) {\n        this.key = key;\n        this.value = value;\n    }\n    \n    public K getKey() { return key; }\n    public V getValue() { return value; }\n}\n\n// उपयोग\nPair<String, Integer> pair = new Pair<>("आयु", 30);\nString key = pair.getKey();\nInteger value = pair.getValue();
\n\n

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

\n

एक मेथड के अपने स्वयं के प्रकार पैरामीटर हो सकते हैं, जो क्लास से संबंधित नहीं हैं:

\n
public class Utils {\n    // ऐरे से लिस्ट बनाने के लिए जेनेरिक मेथड\n    public static <T> List<T> arrayToList(T[] array) {\n        List<T> list = new ArrayList<>();\n        for (T element : array) {\n            list.add(element);\n        }\n        return list;\n    }\n}\n\n// उपयोग\nString[] names = {"अन्ना", "बोरिस", "विक्टर"};\nList<String> nameList = Utils.arrayToList(names);
\n\n

2.3. जेनेरिक इंटरफेसेस

ब्लॉग

पुस्तक अनुशंसाएँ