Java में Generics: शुरुआती लोगों के लिए क्यों ज़रूरी हैं और कैसे उपयोग करें
\n\nयदि आप अभी Java सीखना शुरू कर रहे हैं, तो देर-सबेर आप Generics (सामान्यीकृत प्रकार या जेनेरिक्स) की अवधारणा से परिचित होंगे। भाषा की यह शक्तिशाली क्षमता आपको अधिक लचीला, सुरक्षित और पुन: प्रयोज्य कोड लिखने की अनुमति देती है। इस लेख में हम सरल शब्दों में समझेंगे कि Generics क्या हैं, वे क्यों ज़रूरी हैं और व्यवहार में उनका उपयोग कैसे करें।
\n\nJava में Generics क्या हैं?
\n\nGenerics (अंग्रेजी "generic" से — सामान्य, वंशानुगत) एक Java तंत्र है जो आपको ऐसे क्लासेस, इंटरफेसेस और मेथड्स बनाने की अनुमति देता है जो विभिन्न डेटा प्रकारों के साथ काम करते हैं, लेकिन संकलन चरण में प्रकारों की सख्त जाँच सुनिश्चित करते हैं।
\n\nसीधे शब्दों में कहें तो, जेनेरिक्स आपको यह निर्दिष्ट करने की अनुमति देते हैं: "यह क्लास या मेथड किसी भी डेटा प्रकार के साथ काम करेगा, लेकिन मुझे अभी नहीं पता कि किसके साथ।" प्रकार बाद में निर्धारित किया जाता है, जब आप ऑब्जेक्ट बनाते हैं या मेथड को कॉल करते हैं।
\n\nGenerics के बिना समस्या
\n\nGenerics (Java 5 से पहले) के आगमन से पहले, डेवलपर्स टाइप कास्टिंग का उपयोग करते थे और Object के साथ काम करते थे। यह असुविधाजनक और खतरनाक था:
// Generics के बिना (पुरानी शैली)\nList list = new ArrayList();\nlist.add("नमस्ते");\nlist.add(123); // त्रुटि? नहीं, कंपाइलर इसे अनुमति देगा\n\nString text = (String) list.get(0); // कास्टिंग अनिवार्य\n// String num = (String) list.get(1); // रनटाइम पर ClassCastException!\n\nयहाँ कंपाइलर को त्रुटि नहीं दिखती, लेकिन प्रोग्राम रनटाइम पर क्रैश हो जाएगा। Generics इस समस्या का समाधान करते हैं।
\n\nJava में Generics क्यों ज़रूरी हैं?
\n\nGenerics तीन मुख्य लाभ प्रदान करते हैं:
\n\n- \n
- टाइप सुरक्षा (Type Safety) — त्रुटियाँ संकलन चरण पर पाई जाती हैं, न कि प्रोग्राम के निष्पादन के दौरान। \n
- स्पष्ट कास्टिंग से मुक्ति (No Casting) — हर बार
(String)लिखने की आवश्यकता नहीं है। \n - कोड का पुन: उपयोग (Code Reuse) — एक क्लास या मेथड विभिन्न प्रकारों के साथ काम कर सकता है। \n
Generics के साथ उदाहरण
\n\nदेखें कि जेनेरिक्स के उपयोग से कोड कैसे बदलता है:
\n\n// Generics के साथ\nList<String> list = new ArrayList<>();\nlist.add("नमस्ते");\n// list.add(123); // संकलन त्रुटि! Integer नहीं जोड़ सकते\n\nString text = list.get(0); // कास्टिंग की आवश्यकता नहीं\n// कंपाइलर पहले से जानता है कि यह String है\n\nकोड सरल, सुरक्षित और अधिक पठनीय हो गया है।
\n\nGenerics का उपयोग कैसे करें: मुख्य संरचनाएँ
\n\nआइए जेनेरिक्स के तीन मुख्य अनुप्रयोगों को समझें: क्लासेस, मेथड्स और इंटरफेसेस में।
\n\n1. Generic-क्लासेस
\n\nआप एक ऐसा क्लास बना सकते हैं जो किसी भी प्रकार के साथ काम करता है। इसके लिए क्लास के नाम के बाद कोण कोष्ठक में एक प्रकार पैरामीटर (आमतौर पर T, E, K, V) निर्दिष्ट किया जाता है:
// सामान्यीकृत क्लास "बॉक्स"\npublic class Box<T> {\n private T content;\n\n public void put(T item) {\n this.content = item;\n }\n\n public T get() {\n return content;\n }\n}\n\n// उपयोग\nBox<String> stringBox = new Box<>();\nstringBox.put("पुस्तक");\nString book = stringBox.get(); // बिना कास्टिंग के\n\nBox<Integer> intBox = new Box<>();\nintBox.put(42);\nint number = intBox.get();\n\n2. Generic-मेथड्स
\n\nपूरे क्लास को नहीं, बल्कि केवल एक अलग मेथड को सामान्यीकृत किया जा सकता है। यह तब उपयोगी होता है जब मेथड को क्लास से स्वतंत्र रूप से विभिन्न प्रकारों को संसाधित करना हो:
\n\npublic class Utils {\n // सामान्यीकृत मेथड\n public static <T> void printArray(T[] array) {\n for (T element : array) {\n System.out.print(element + " ");\n }\n System.out.println();\n }\n}\n\n// कॉल\nInteger[] intArray = {1, 2, 3};\nString[] strArray = {"A", "B", "C"};\n\nUtils.printArray(intArray); // 1 2 3\nUtils.printArray(strArray); // A B C\n\n3. Generic-इंटरफेसेस
\n\nइंटरफेस