परिचय: एक क्लास के तीन नाम — कैसे भ्रमित न हों?
\n\nहर Java डेवलपर, जिसने कभी रिफ्लेक्शन की दुनिया में झाँका है, तीन प्रतीत होने वाले समान तरीकों का सामना किया है: getName(), getSimpleName() और getCanonicalName()। पहली नज़र में ये सभी क्लास का नाम लौटाते हैं। लेकिन जैसे ही आंतरिक क्लास, ऐरे या अनाम क्लास खेल में आते हैं, भ्रम शुरू हो जाता है। यही वह प्रश्न है जिसने Stack Overflow पर हज़ारों व्यूज़ एकत्र किए हैं, और आज हम हमेशा के लिए समझ लेंगे कि अंतर क्या है।
इस लेख में हम केवल परिभाषाएँ सूचीबद्ध नहीं करेंगे, बल्कि वास्तविक कोड उदाहरणों के साथ दिखाएंगे कि ये विधियाँ कैसे काम करती हैं। आप जानेंगे कि प्रत्येक का उपयोग कब करना है और कौन से छिपे हुए नुकसान आपका इंतजार कर रहे हैं। चलिए शुरू करते हैं!
\n\n1. मूल अवधारणाएँ: प्रत्येक विधि क्या लौटाती है?
\n\nगहराई में जाने से पहले, आइए परिभाषित करें कि Java Class API के संदर्भ में इन शब्दों का वास्तव में क्या अर्थ है।
\n\n- \n
- Simple Name (
getSimpleName()): सबसे छोटा नाम। यह पैकेज के बिना केवल क्लास का नाम है। आंतरिक क्लास के लिए — केवल सबसे अंदरूनी क्लास का नाम। \n - Class Name (
getName()): पूरा नाम, लेकिन JVM की आंतरिक संरचना को ध्यान में रखते हुए। सामान्य क्लास के लिए — यह package + class है। आंतरिक क्लास के लिए — विभाजक$का उपयोग किया जाता है। ऐरे के लिए — वर्गाकार कोष्ठक जोड़े जाते हैं। \n - Canonical Name (
getCanonicalName()): "विहित" नाम जिसका उपयोग स्रोत कोड में वेरिएबल घोषित करने के लिए किया जा सकता है। यह उस तरीके के सबसे करीब है जिससे आप कोड लिखते हैं: डॉलर के बजाय डॉट्स के साथ। \n
अमूर्त लगता है? आइए इसे कोड के साथ पुष्ट करें।
\n\n2. सामान्य क्लास के साथ उदाहरण
\n\nआइए सबसे सरल से शुरू करें — बिना किसी नेस्टिंग के एक सामान्य क्लास।
\n\n// फ़ाइल: com/example/MyClass.java\npackage com.example;\n\npublic class MyClass {\n public static void main(String[] args) {\n System.out.println("Simple Name: " + MyClass.class.getSimpleName());\n System.out.println("Class Name: " + MyClass.class.getName());\n System.out.println("Canonical Name: " + MyClass.class.getCanonicalName());\n }\n}\n\nपरिणाम:
\nSimple Name: MyClass\nClass Name: com.example.MyClass\nCanonical Name: com.example.MyClass\n\nजैसा कि आप देख सकते हैं, सामान्य क्लास के लिए getName() और getCanonicalName() बिल्कुल समान हैं। getSimpleName() पैकेज को हटा देता है। कोई जादू नहीं।
3. आंतरिक (नेस्टेड) क्लास: जहाँ जादू शुरू होता है
\n\nअब कल्पना करें कि हमारे पास एक आंतरिक क्लास है। यहीं पर मुख्य अंतर सामने आता है।
\n\npackage com.example;\n\npublic class OuterClass {\n public static class InnerClass {\n public void printNames() {\n System.out.println("Simple: " + getClass().getSimpleName());\n System.out.println("Class: " + getClass().getName());\n System.out.println("Canonical: " + getClass().getCanonicalName());\n }\n }\n\n public static void main(String[] args) {\n InnerClass inner = new InnerClass();\n inner.printNames();\n }\n}\n\nपरिणाम:
\nSimple: InnerClass\nClass: com.example.OuterClass$InnerClass\nCanonical: com.example.OuterClass.InnerClass\n\nयह रहा! अंतर स्पष्ट हो जाता है:
\n- \n
getSimpleName()ने केवलInnerClassलौटाया। \n getName()मूल और आंतरिक क्लास को अलग करने के लिए प्रतीक$का उपयोग करता है। यह JVM का आंतरिक प्रतिनिधित्व है। \n getCanonicalName()डॉट का उपयोग करता है — जैसे आप कोड में लिखेंगे:OuterClass.InnerClass। \n
इसी $ प्रतीक के कारण कई शुरुआती बग पकड़ते हैं, जब वे <