जावा वर्ग में विहित नाम, सरल नाम और वर्ग नाम के बीच अंतर क्या है?


972

जावा में, इनमें क्या अंतर है:

Object o1 = ....
o1.getClass().getSimpleName();
o1.getClass().getName();
o1.getClass().getCanonicalName();

मैंने कई बार जावदोक की जाँच की है और फिर भी यह इसे अच्छी तरह से समझाता है। मैंने एक परीक्षण भी चलाया और उस तरीके के पीछे किसी भी वास्तविक अर्थ को प्रतिबिंबित नहीं किया।



218
मुझे लगता है कि यह एक उचित सवाल है। जावदोक तीनों के बीच के अंतर को समझाने का अच्छा काम नहीं करता है।
ग्राहम बोरलैंड

1
देखें - docs.oracle.com/javase/6/docs/api/java/lang/Class.html या शायद सिर्फ एक परीक्षा लिखें।
निक होल्ट

7
@GrahamBorland javadoc "जावा भाषा विशिष्टता द्वारा परिभाषित" के रूप में कहता है - ताकि आप इसे उस दस्तावेज़ में देख सकें। सिर्फ इसलिए कि यह एक क्लिक करने योग्य लिंक नहीं है लोग अभी भी एक न्यूनतम प्रयास कर सकते हैं और पहले खोज इंजन परिणाम पर क्लिक कर सकते हैं।
vbence

66
@vbence: ज्यादातर लोग बल्कि इस तरह से तुच्छ चीजों के लिए जेएलएस देखने के बजाय काम किया जाएगा। इसलिए, यह पहला Google परिणाम है :)
pathikrit

जवाबों:


1129

यदि आप किसी चीज़ के बारे में अनिश्चित हैं, तो पहले परीक्षण लिखने का प्रयास करें।

इसे मैने किया है:

class ClassNameTest {
    public static void main(final String... arguments) {
        printNamesForClass(
            int.class,
            "int.class (primitive)");
        printNamesForClass(
            String.class,
            "String.class (ordinary class)");
        printNamesForClass(
            java.util.HashMap.SimpleEntry.class,
            "java.util.HashMap.SimpleEntry.class (nested class)");
        printNamesForClass(
            new java.io.Serializable(){}.getClass(),
            "new java.io.Serializable(){}.getClass() (anonymous inner class)");
    }

    private static void printNamesForClass(final Class<?> clazz, final String label) {
        System.out.println(label + ":");
        System.out.println("    getName():          " + clazz.getName());
        System.out.println("    getCanonicalName(): " + clazz.getCanonicalName());
        System.out.println("    getSimpleName():    " + clazz.getSimpleName());
        System.out.println("    getTypeName():      " + clazz.getTypeName()); // added in Java 8
        System.out.println();
    }
}

प्रिंटों:

int.class (आदिम):
    getName (): int
    getCanonicalName (): int
    getSimpleName (): int
    getTypeName (): int

String.class (साधारण वर्ग):
    getName (): java.lang.String
    getCanonicalName (): java.lang.String
    getSimpleName (): स्ट्रिंग
    getTypeName (): java.lang.String

java.util.HashMap.SimpleEntry.class (नेस्टेड क्लास):
    getName (): java.util.AbstractMap $ SimpleEntry
    getCanonicalName (): java.util.AbstractMap.SimpleEntry
    getSimpleName (): SimpleEntry
    getTypeName (): java.util.AbstractMap $ SimpleEntry

नया java.io.Serializable () {}। getClass () (अनाम आंतरिक वर्ग):
    getName (): ClassNameTest $ 1
    getCanonicalName (): null
    getSimpleName ():    
    getTypeName (): ClassNameTest $ 1

अंतिम ब्लॉक में एक खाली प्रविष्टि है जहां getSimpleNameएक खाली स्ट्रिंग लौटाता है।

यह देख रहा है:

  • नाम वह नाम है जिसका उपयोग आप कक्षा को गतिशील रूप से लोड करने के लिए करेंगे, उदाहरण के लिए, Class.forNameडिफ़ॉल्ट के साथ कॉल ClassLoader। एक निश्चित के दायरे में ClassLoader, सभी वर्गों के अद्वितीय नाम हैं।
  • विहित नाम ऐसा नाम है जो एक आयात बयान में इस्तेमाल किया जाएगा है। toStringसंचालन के दौरान या लॉगिंग के दौरान यह उपयोगी हो सकता है । जब javacकंपाइलर के पास एक क्लासपाथ का पूरा दृश्य होता है, तो यह संकलन के समय पूरी तरह से योग्य वर्ग और पैकेज के नामों को टकराकर इसके भीतर विहित नामों की विशिष्टता को लागू करता है। हालाँकि JVM को इस तरह के नाम के टकराव को स्वीकार करना चाहिए, और इस प्रकार विहित नाम विशिष्ट रूप से वर्गों की पहचान नहीं करते हैं ClassLoader। (हिंडाइट में, इस गेट्टर का एक बेहतर नाम होगा getJavaName; लेकिन यह विधि ऐसे समय से शुरू होती है जब JVM का उपयोग केवल जावा प्रोग्राम चलाने के लिए किया गया था।)
  • सरल नाम शिथिल के दौरान फिर से, वर्ग की पहचान करता है उपयोगी हो सकता है toStringया प्रवेश संचालन लेकिन अद्वितीय होने की गारंटी नहीं है।
  • प्रकार का नाम रिटर्न, "यह) toString (की तरह है: यह पूरी तरह जानकारीपूर्ण है और कोई अनुबंध मूल्य है" "इस प्रकार के नाम के लिए एक जानकारीपूर्ण स्ट्रिंग" (के रूप में sir4ur0n द्वारा लिखित)

5
आपको क्या लगता है कि अतिरिक्त क्या चाहिए?
निक होल्ट

2
@ अनुपमसाईं हां। एक असली आवेदन में इस तरह के एक पैकेज का नाम होना पागल होगा।
जयन

3
हालांकि, पागल हो जाएगा, हालांकि, इस तरह की धारणा है जो एक दुर्भावनापूर्ण अभिनेता को काम करने की अनुमति देगा। कोई कह रहा है "ओह, हम अच्छी तरह से जानते हैं कि कक्षाएं लोअरकेस से शुरू नहीं होंगी / पैकेज कभी भी राजधानियों से शुरू नहीं होंगे"। दी, एक दुर्भावनापूर्ण अभिनेता जो आपके वर्ग लोडर तक पहुंच रखता है, पहले से ही भयानक काम कर सकता है, इसलिए यह बिल्कुल भयानक धारणा नहीं है।
corsiKa

2
@PieterDeBie कैसे? आपको बस इतना पता होना चाहिए कि वह विधि नाम है जिसे आप परीक्षण करना चाहते हैं।
fool4jesus

20
Java 8 ने getTypeName () को भी जोड़ा ... उसके लिए अद्यतन करने की परवाह है?
थियोडोर मर्डॉक

90

toString()पिछले दो उत्तरों को पूरा करने के लिए स्थानीय कक्षाओं, लंबोदा और विधि को जोड़ना । इसके अलावा, मैं लंबोदर और अनाम कक्षाओं के सरणियों को जोड़ता हूं (हालांकि अभ्यास में कोई मतलब नहीं है):

package com.example;

public final class TestClassNames {
    private static void showClass(Class<?> c) {
        System.out.println("getName():          " + c.getName());
        System.out.println("getCanonicalName(): " + c.getCanonicalName());
        System.out.println("getSimpleName():    " + c.getSimpleName());
        System.out.println("toString():         " + c.toString());
        System.out.println();
    }

    private static void x(Runnable r) {
        showClass(r.getClass());
        showClass(java.lang.reflect.Array.newInstance(r.getClass(), 1).getClass()); // Obtains an array class of a lambda base type.
    }

    public static class NestedClass {}

    public class InnerClass {}

    public static void main(String[] args) {
        class LocalClass {}
        showClass(void.class);
        showClass(int.class);
        showClass(String.class);
        showClass(Runnable.class);
        showClass(SomeEnum.class);
        showClass(SomeAnnotation.class);
        showClass(int[].class);
        showClass(String[].class);
        showClass(NestedClass.class);
        showClass(InnerClass.class);
        showClass(LocalClass.class);
        showClass(LocalClass[].class);
        Object anonymous = new java.io.Serializable() {};
        showClass(anonymous.getClass());
        showClass(java.lang.reflect.Array.newInstance(anonymous.getClass(), 1).getClass()); // Obtains an array class of an anonymous base type.
        x(() -> {});
    }
}

enum SomeEnum {
   BLUE, YELLOW, RED;
}

@interface SomeAnnotation {}

यह पूर्ण आउटपुट है:

getName():          void
getCanonicalName(): void
getSimpleName():    void
toString():         void

getName():          int
getCanonicalName(): int
getSimpleName():    int
toString():         int

getName():          java.lang.String
getCanonicalName(): java.lang.String
getSimpleName():    String
toString():         class java.lang.String

getName():          java.lang.Runnable
getCanonicalName(): java.lang.Runnable
getSimpleName():    Runnable
toString():         interface java.lang.Runnable

getName():          com.example.SomeEnum
getCanonicalName(): com.example.SomeEnum
getSimpleName():    SomeEnum
toString():         class com.example.SomeEnum

getName():          com.example.SomeAnnotation
getCanonicalName(): com.example.SomeAnnotation
getSimpleName():    SomeAnnotation
toString():         interface com.example.SomeAnnotation

getName():          [I
getCanonicalName(): int[]
getSimpleName():    int[]
toString():         class [I

getName():          [Ljava.lang.String;
getCanonicalName(): java.lang.String[]
getSimpleName():    String[]
toString():         class [Ljava.lang.String;

getName():          com.example.TestClassNames$NestedClass
getCanonicalName(): com.example.TestClassNames.NestedClass
getSimpleName():    NestedClass
toString():         class com.example.TestClassNames$NestedClass

getName():          com.example.TestClassNames$InnerClass
getCanonicalName(): com.example.TestClassNames.InnerClass
getSimpleName():    InnerClass
toString():         class com.example.TestClassNames$InnerClass

getName():          com.example.TestClassNames$1LocalClass
getCanonicalName(): null
getSimpleName():    LocalClass
toString():         class com.example.TestClassNames$1LocalClass

getName():          [Lcom.example.TestClassNames$1LocalClass;
getCanonicalName(): null
getSimpleName():    LocalClass[]
toString():         class [Lcom.example.TestClassNames$1LocalClass;

getName():          com.example.TestClassNames$1
getCanonicalName(): null
getSimpleName():    
toString():         class com.example.TestClassNames$1

getName():          [Lcom.example.TestClassNames$1;
getCanonicalName(): null
getSimpleName():    []
toString():         class [Lcom.example.TestClassNames$1;

getName():          com.example.TestClassNames$$Lambda$1/1175962212
getCanonicalName(): com.example.TestClassNames$$Lambda$1/1175962212
getSimpleName():    TestClassNames$$Lambda$1/1175962212
toString():         class com.example.TestClassNames$$Lambda$1/1175962212

getName():          [Lcom.example.TestClassNames$$Lambda$1;
getCanonicalName(): com.example.TestClassNames$$Lambda$1/1175962212[]
getSimpleName():    TestClassNames$$Lambda$1/1175962212[]
toString():         class [Lcom.example.TestClassNames$$Lambda$1;

तो, यहाँ नियम हैं। सबसे पहले, आदिम प्रकार के साथ शुरू करते हैं और void:

  1. यदि क्लास ऑब्जेक्ट एक आदिम प्रकार का प्रतिनिधित्व करता है या void, सभी चार विधियां बस अपना नाम वापस करती हैं।

अब getName()विधि के नियम :

  1. प्रत्येक गैर-लंबा और गैर-सरणी वर्ग या इंटरफ़ेस (यानी, शीर्ष-स्तर, नेस्टेड, आंतरिक, स्थानीय और अनाम) का एक नाम है (जो कि वापस आ गया है getName()) पैकेज नाम है जिसके बाद एक डॉट (यदि कोई पैकेज है) ), संकलक (प्रत्यय को मिलाकर .class) के रूप में उत्पन्न उसकी कक्षा-फ़ाइल के नाम के बाद । यदि कोई पैकेज नहीं है, तो यह केवल क्लास-फाइल का नाम है। यदि क्लास एक आंतरिक, नेस्टेड, स्थानीय या अनाम वर्ग है, तो कंपाइलर को $उसके क्लास-फाइल नाम में कम से कम एक उत्पन्न करना चाहिए । ध्यान दें कि अनाम कक्षाओं के लिए, वर्ग का नाम एक डॉलर-चिह्न के साथ समाप्त हो जाएगा और उसके बाद एक नंबर होगा।
  2. लैम्ब्डा वर्ग के नाम आम तौर पर अप्रत्याशित होते हैं, और आपको उनकी परवाह नहीं करनी चाहिए। वास्तव में, उनका नाम संलग्न वर्ग का नाम है $$Lambda$, उसके बाद एक संख्या, उसके बाद एक स्लैश, उसके बाद एक अन्य संख्या है।
  3. पुरातन के वर्ग वर्णनकर्ता हैं Zके लिए boolean, Bके लिए byte, Sके लिए short, Cके लिए char, Iके लिए int, Jके लिए long, Fके लिए floatऔर Dके लिए double। गैर-सरणी वर्गों और इंटरफेस के लिए वर्ग विवरणक इसके Lबाद क्या दिया जाता getName()है ;। सरणी वर्गों के लिए, क्लास डिस्क्रिप्टर [घटक प्रकार के क्लास डिस्क्रिप्टर (जो स्वयं एक और एरे क्लास हो सकता है) के बाद आता है।
  4. सरणी कक्षाओं के लिए, getName()विधि अपने वर्ग के विवरणक को लौटा देती है। यह नियम केवल सरणी वर्गों के लिए विफल होता है जिसका घटक प्रकार एक लैम्ब्डा है (जो संभवतः एक बग है), लेकिन उम्मीद है कि यह वैसे भी मायने नहीं रखना चाहिए क्योंकि सरणी वर्गों के अस्तित्व पर भी कोई मतलब नहीं है जिसका घटक प्रकार एक लैम्ब्डा है।

अब, toString()विधि:

  1. यदि वर्ग उदाहरण इंटरफ़ेस (या एनोटेशन, जो एक विशेष प्रकार का इंटरफ़ेस है) का प्रतिनिधित्व करता है, तो toString()रिटर्न "interface " + getName()। यदि यह एक आदिम है, तो यह सरलता से लौटता है getName()। यदि यह कुछ और है (एक वर्ग प्रकार, भले ही यह बहुत अजीब हो), यह वापस आ जाता है "class " + getName()

getCanonicalName()विधि:

  1. शीर्ष-स्तरीय कक्षाओं और इंटरफेस के लिए, getCanonicalName()विधि वही लौटाती है जो getName()विधि लौटाती है।
  2. यह getCanonicalName()विधि nullअनाम या स्थानीय कक्षाओं के लिए और उन लोगों की सरणी कक्षाओं के लिए वापस आती है ।
  3. आंतरिक और नेस्टेड वर्गों और इंटरफेस के लिए, getCanonicalName()विधि रिटर्न करती है कि क्या getName()विधि डॉट्स द्वारा संकलक-शुरू किए गए डॉलर-संकेतों की जगह लेगी।
  4. सरणी वर्गों के लिए, getCanonicalName()विधि वापस आती है nullयदि घटक प्रकार का विहित नाम है null। अन्यथा, यह घटक प्रकार के विहित नाम का अनुसरण करता है []

getSimpleName()विधि:

  1. शीर्ष-स्तर, नेस्टेड, आंतरिक और स्थानीय कक्षाओं के लिए, getSimpleName()स्रोत फ़ाइल में लिखे अनुसार कक्षा का नाम देता है।
  2. अनाम कक्षाओं के लिए getSimpleName()रिटर्न एक खाली है String
  3. लैम्ब्डा क्लासेस के लिए getSimpleName()सिर्फ getName()पैकेज नाम के बिना क्या रिटर्न होगा। यह बहुत मायने नहीं रखता है और मेरे लिए एक बग जैसा दिखता है, लेकिन getSimpleName()शुरू करने के लिए एक लैम्ब्डा क्लास पर कॉल करने का कोई मतलब नहीं है ।
  4. सरणी वर्गों के लिए getSimpleName()विधि घटक वर्ग के सरल नाम का अनुसरण करती है []। यह अजीब / अजीब साइड-इफेक्ट है कि सरणी वर्ग जिनके घटक प्रकार एक अनाम वर्ग है []उनके साधारण नाम के समान है।

2
… replacing the dollar-signs by dots: केवल डॉलर के संकेत जो परिसीमनकर्ता के रूप में पेश किए गए थे, प्रतिस्थापित किए जा रहे हैं। आपके पास एक सरल नाम के हिस्से के रूप में अच्छी तरह से डॉलर हो सकते हैं, और वे जगह में रहेंगे।
MvG

अरे नहीं! वर्ग नाम के हिस्से के रूप में! मैं एक क्लास ट्रांसफ़ॉर्मर विकसित कर रहा हूं और मुझे लगा कि '/' क्लास और पैकेज के नाम के बीच एक सुरक्षित सीमांकक होगा: /
जोस रॉबर्टो आराजो जूनियर

81

निक होल्ट की टिप्पणियों के अलावा, मैंने Arrayडेटा प्रकार के लिए कुछ मामलों को चलाया :

//primitive Array
int demo[] = new int[5];
Class<? extends int[]> clzz = demo.getClass();
System.out.println(clzz.getName());
System.out.println(clzz.getCanonicalName());
System.out.println(clzz.getSimpleName());       

System.out.println();


//Object Array
Integer demo[] = new Integer[5]; 
Class<? extends Integer[]> clzz = demo.getClass();
System.out.println(clzz.getName());
System.out.println(clzz.getCanonicalName());
System.out.println(clzz.getSimpleName());

ऊपर कोड स्निपेट प्रिंट:

[I
int[]
int[]

[Ljava.lang.Integer;
java.lang.Integer[]
Integer[]

28
उपर्युक्त उत्तर को संपादित करने का प्रस्ताव देना बेहतर नहीं होगा।
लोकी

17

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

निम्नलिखित उदाहरण पर विचार करें:

package a.b;
class C {
  static class D extends C {
  }
  D d;
  D[] ds;
}
  • सरल नाम की Dहै D। वह केवल वह हिस्सा है जिसे आपने कक्षा घोषित करते समय लिखा था। अनाम वर्गों का कोई सरल नाम नहीं है। Class.getSimpleName()यह नाम या खाली स्ट्रिंग लौटाता है। सरल नाम के लिए यह संभव है कि $यदि आप इसे इस तरह लिखते हैं, चूंकि जेएलएस सेक्शन 3.8 (भले ही यह कुछ हतोत्साहित हो) के $अनुसार एक पहचानकर्ता का एक मान्य हिस्सा है ।

  • के अनुसार JLS खंड 6.7 , दोनों a.b.C.Dऔर a.b.C.D.D.Dकिया जाएगा पूरी तरह से योग्य नाम है, लेकिन केवल a.b.C.Dहोगा विहित नाम की D। यूं तो हर विहित नाम पूरी तरह से योग्य नाम है, लेकिन काफिला हमेशा सच नहीं होता है। Class.getCanonicalName()विहित नाम वापस करेगा या null

  • Class.getName()द्विआधारी नाम वापस करने के लिए प्रलेखित है , जैसा कि जेएलएस अनुभाग 13.1 में निर्दिष्ट है । इस मामले में यह रिटर्न a.b.C$Dके लिए Dऔर [La.b.C$D;के लिए D[]

  • यह उत्तर दर्शाता है कि एक ही श्रेणी लोडर द्वारा एक ही कैनोनिकल नाम लेकिन अलग-अलग द्विआधारी नामों के लिए लोड किए गए दो वर्गों के लिए संभव है । न तो नाम पर्याप्त रूप से दूसरे को कम करने के लिए पर्याप्त है: यदि आपके पास विहित नाम है, तो आपको नहीं पता कि नाम के कौन से हिस्से पैकेज हैं और जिनमें कक्षाएं शामिल हैं। यदि आपके पास द्विआधारी नाम है, तो आप नहीं जानते कि कौन $से विभाजक के रूप में पेश किए गए थे और जो कुछ सरल नाम का हिस्सा थे। (वर्ग फ़ाइल भंडार द्विआधारी नाम की कक्षा में ही है और इसकी enclosing वर्ग है, जो क्रम के लिए अनुमति देता यह भेद करना ।)

  • अनाम वर्गों और स्थानीय कक्षाओं में पूरी तरह से योग्य नाम नहीं हैं, लेकिन फिर भी एक द्विआधारी नाम है । ऐसी कक्षाओं के अंदर निहित वर्गों के लिए भी यही स्थिति है। हर वर्ग का एक बाइनरी नाम है।

  • चल रहा है javap -v -privateपर a/b/C.classपता चलता है कि बाईटकोड के प्रकार को संदर्भित करता है dके रूप में La/b/C$D;और सरणी की है कि dsके रूप में [La/b/C$D;। इन्हें विवरणकर्ता कहा जाता है , और वे JVMS खंड 4.3 में निर्दिष्ट हैं ।

  • वर्ग के नाम a/b/C$Dइन वर्णनकर्ता के दोनों में इस्तेमाल किया आप को बदल कर प्राप्त होता है .द्वारा /द्विआधारी नाम पर। JVM स्पेक जाहिरा तौर पर इसे बाइनरी नाम का आंतरिक रूप कहता है । JVMS अनुभाग 4.2.1 इसका वर्णन करता है, और बताता है कि बाइनरी नाम से अंतर ऐतिहासिक कारणों से था।

  • किसी विशिष्ट फ़ाइलनाम-आधारित क्लास लोडर में एक वर्ग का फ़ाइल नाम वह है जो आपको मिलता है यदि आप /द्विपदीय नाम के आंतरिक रूप में एक निर्देशिका विभाजक के रूप में व्याख्या करते हैं , और फ़ाइल नाम एक्सटेंशन .classको संलग्न करते हैं । यह प्रश्न में वर्ग लोडर द्वारा उपयोग किए जाने वाले वर्ग पथ के सापेक्ष हल हो गया है।


3
यह स्वीकृत उत्तर होना चाहिए क्योंकि यह एकमात्र उत्तर है जो जेएलएस को संदर्भित करता है और उचित शब्दावली का उपयोग करता है।
जॉन

10

यह सबसे अच्छा दस्तावेज है जो मुझे getName (), getSimpleName (), getCanonicalName () का वर्णन करते हुए मिला है

https://javahowtodoit.wordpress.com/2014/09/09/java-lang-class-what-is-the-difference-between-class-getname-class-getcanonicalname-and-class-getsimplename/

// Primitive type
int.class.getName();          // -> int
int.class.getCanonicalName(); // -> int
int.class.getSimpleName();    // -> int

// Standard class
Integer.class.getName();          // -> java.lang.Integer
Integer.class.getCanonicalName(); // -> java.lang.Integer
Integer.class.getSimpleName();    // -> Integer

// Inner class
Map.Entry.class.getName();          // -> java.util.Map$Entry
Map.Entry.class.getCanonicalName(); // -> java.util.Map.Entry
Map.Entry.class.getSimpleName();    // -> Entry     

// Anonymous inner class
Class<?> anonymousInnerClass = new Cloneable() {}.getClass();
anonymousInnerClass.getName();          // -> somepackage.SomeClass$1
anonymousInnerClass.getCanonicalName(); // -> null
anonymousInnerClass.getSimpleName();    // -> // An empty string

// Array of primitives
Class<?> primitiveArrayClass = new int[0].getClass();
primitiveArrayClass.getName();          // -> [I
primitiveArrayClass.getCanonicalName(); // -> int[]
primitiveArrayClass.getSimpleName();    // -> int[]

// Array of objects
Class<?> objectArrayClass = new Integer[0].getClass();
objectArrayClass.getName();          // -> [Ljava.lang.Integer;
objectArrayClass.getCanonicalName(); // -> java.lang.Integer[]
objectArrayClass.getSimpleName();    // -> Integer[]

3

ऐसा नहीं है कि नोट करने के लिए दिलचस्प है getCanonicalName()और getSimpleName()बढ़ा सकते हैं InternalErrorजब वर्ग के नाम विकृत है। यह कुछ गैर-जावा जेवीएम भाषाओं, जैसे, स्काला के लिए होता है।

निम्नलिखित पर विचार करें (जावा 8 पर स्केल 2.11):

scala> case class C()
defined class C

scala> val c = C()
c: C = C()

scala> c.getClass.getSimpleName
java.lang.InternalError: Malformed class name
  at java.lang.Class.getSimpleName(Class.java:1330)
  ... 32 elided

scala> c.getClass.getCanonicalName
java.lang.InternalError: Malformed class name
  at java.lang.Class.getSimpleName(Class.java:1330)
  at java.lang.Class.getCanonicalName(Class.java:1399)
  ... 32 elided

scala> c.getClass.getName
res2: String = C

यह मिश्रित भाषा वातावरण या वातावरण के लिए एक समस्या हो सकती है जो गतिशील रूप से बायटेकोड, उदाहरण के लिए, ऐप सर्वर और अन्य प्लेटफ़ॉर्म सॉफ़्टवेयर को लोड करता है।


1
    public void printReflectionClassNames(){
    StringBuffer buffer = new StringBuffer();
    Class clazz= buffer.getClass();
    System.out.println("Reflection on String Buffer Class");
    System.out.println("Name: "+clazz.getName());
    System.out.println("Simple Name: "+clazz.getSimpleName());
    System.out.println("Canonical Name: "+clazz.getCanonicalName());
    System.out.println("Type Name: "+clazz.getTypeName());
}

outputs:
Reflection on String Buffer Class
Name: java.lang.StringBuffer
Simple Name: StringBuffer
Canonical Name: java.lang.StringBuffer
Type Name: java.lang.StringBuffer

1
विधि के अंदर पहली दो पंक्तियों को कम किया जा सकता हैClass<StringBuffer> clazz = StringBuffer.class
ThePyroEagle

1

getName () - एक String के रूप में इस क्लास ऑब्जेक्ट द्वारा दर्शाए गए इकाई (वर्ग, इंटरफ़ेस, सरणी वर्ग, आदिम प्रकार, या शून्य) का नाम देता है।

getCanonicalName () - जावा भाषा विनिर्देश द्वारा परिभाषित अंतर्निहित वर्ग का विहित नाम देता है।

getSimpleName () - अंतर्निहित वर्ग का सरल नाम लौटाता है, यही वह नाम है जिसे स्रोत कोड में दिया गया है।

package com.practice;

public class ClassName {
public static void main(String[] args) {

  ClassName c = new ClassName();
  Class cls = c.getClass();

  // returns the canonical name of the underlying class if it exists
  System.out.println("Class = " + cls.getCanonicalName());    //Class = com.practice.ClassName
  System.out.println("Class = " + cls.getName());             //Class = com.practice.ClassName
  System.out.println("Class = " + cls.getSimpleName());       //Class = ClassName
  System.out.println("Class = " + Map.Entry.class.getName());             // -> Class = java.util.Map$Entry
  System.out.println("Class = " + Map.Entry.class.getCanonicalName());    // -> Class = java.util.Map.Entry
  System.out.println("Class = " + Map.Entry.class.getSimpleName());       // -> Class = Entry 
  }
}

एक अंतर यह है कि यदि आप एक अनाम वर्ग का उपयोग करते हैं तो आप कक्षा का नाम प्राप्त करने का प्रयास करते समय एक अशक्त मूल्य प्राप्त कर सकते हैंgetCanonicalName()

एक और तथ्य यह है कि getName()विधि आंतरिक वर्गों केgetCanonicalName() लिए विधि की तुलना में अलग व्यवहार करती है । संलग्नक वर्ग विहित नाम और आंतरिक वर्ग सरल नाम के बीच विभाजक के रूप में एक डॉलर का उपयोग करता है।getName()

जावा में एक वर्ग का नाम प्राप्त करने के बारे में अधिक जानने के लिए ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.