ජාවා පන්තියේ කැනොනිකල් නම, සරල නම සහ පන්තියේ නම අතර වෙනස කුමක්ද?


993

ජාවාහි, මේවා අතර ඇති වෙනස කුමක්ද:

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

මම ජාවාඩොක් කිහිප වතාවක් පරීක්ෂා කර ඇති නමුත් මෙය කිසි විටෙකත් එය හොඳින් පැහැදිලි නොකරයි. මම ද පරීක්‍ෂණයක් පැවැත්වූ අතර එමඟින් මෙම ක්‍රම හඳුන්වන ආකාරය පිටුපස සැබෑ අර්ථයක් නොපෙන්වයි.



221
මම හිතන්නේ මෙය සාධාරණ ප්‍රශ්නයක්. තිදෙනා අතර වෙනස පැහැදිලි කිරීම සඳහා ජාවාඩොක් හොඳ කාර්යයක් නොකරයි.
ග්‍රැහැම් බෝර්ලන්ඩ්

1
බලන්න - docs.oracle.com/javase/6/docs/api/java/lang/Class.html හෝ පරීක්ෂණයක් ලියන්න.
නික් හෝල්ට්

7
RaGrahamBorland javadoc පවසන්නේ "ජාවා භාෂා පිරිවිතරයෙන් අර්ථ දක්වා ඇති පරිදි" - එබැවින් ඔබට එය එම ලේඛනයෙන් සොයාගත හැකිය. එය ක්ලික් කළ හැකි සම්බන්ධකයක් නොවන නිසා මිනිසුන්ට අවම උත්සාහයක් කළ හැකි අතර පළමු සෙවුම් යන්ත්‍ර ප්‍රති .ලය මත ක්ලික් කරන්න.
vbence

67
bvbence: මේ වගේ සුළු දේවල් සඳහා ජේඑල්එස් දෙස බැලීමට වඩා බොහෝ අය දේවල් කර ගැනීමට කැමතියි. එබැවින් මෙය පළමු ගූගල්
ප්‍රති result ලය වේ

Answers:


1152

ඔබට යමක් ගැන සැකයක් ඇත්නම්, පළමුව පරීක්ෂණයක් ලිවීමට උත්සාහ කරන්න.

මම මෙය කළා:

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 $ සරල එන්ට්‍රි
    getCanonicalName (): java.util.AbstractMap.SimpleEntry
    getSimpleName (): සරල එන්ට්‍රි
    getTypeName (): java.util.AbstractMap $ SimpleEntry

නව java.io.Serializable () get}. getClass () (නිර්නාමික අභ්‍යන්තර පන්තිය):
    getName (): ClassNameTest $ 1
    getCanonicalName (): ශූන්‍යය
    getSimpleName ():    
    getTypeName (): ClassNameTest $ 1

අන්තිම කොටසෙහි හිස් ඇතුල්වීමක් ඇත, එහිදී getSimpleNameහිස් නූලක් ලැබේ.

මෙය දෙස බලන ප්‍රති shot ලය:

  • මෙම නම ඔබ වෙත ඇමතුමක්, උදාහරණයක් ලෙස, ගතිකව සමග පන්ති පැටවීම සඳහා භාවිතා කැමතියි බව නම Class.forNameසමඟ, ප්රකෘති ClassLoader. එක්තරා විෂය පථයක් තුළ ClassLoader, සියලුම පංතිවලට අද්විතීය නම් ඇත.
  • මෙම ආගමික තේමා නාමය ආනයන ප්රකාශය භාවිතා කළ බව නම. toStringමෙහෙයුම් අතරතුර හෝ ලොග් වීම ප්‍රයෝජනවත් විය හැකිය . වූ විට javacසම්පාදක වූ classpath සම්පූර්ණ දැක්ම ඇත, එය බැදීමකට සම්පූර්ණ සුදුසුකම් පන්තිය හා ඇසුරුම් නාමයන් ගැටෙමින් විසින් එය තුල කැනෝනිකල් නම් විශේෂත්වය අනුබල. කෙසේ වෙතත්, JVMs එවැනි නාම ගැටුම් පිළිගත යුතු අතර, ඒ අනුව කැනොනිකල් නම් a තුළ පන්ති අද්විතීය ලෙස හඳුනා නොගනී ClassLoader. (පසු විපරමකදී, මෙම ලබා ගන්නා තැනැත්තාට වඩා හොඳ නමක් තිබෙන්නට ඇත getJavaName; නමුත් මෙම ක්‍රමය ආරම්භ වන්නේ ජාවා වැඩසටහන් ක්‍රියාත්මක කිරීම සඳහා පමණක් ජේවීඑම් භාවිතා කළ කාලයක සිට ය.)
  • මෙම සරල නම ලිහිල්ව නැවත තුළ ප්රයෝජනවත් විය හැකි, පන්ති හඳුනා toStringමෙහෙයුම් හෝ ප්රවිශ්ට නමුත් අනන්ය විය සහතික කර නැත.
  • වර්ගයෙහි නම " මෙම වර්ගයේ නම සඳහා තොරතුරු දාමයක්", "එය toString () වැනි ය: එය තනිකරම තොරතුරු සහ කොන්ත්‍රාත් වටිනාකමක් නැත" (sir4ur0n විසින් ලියන ලද පරිදි)

5
අවශ්‍ය වන්නේ කුමක්දැයි ඔබ සිතන්නේ කුමක්ද?
නික් හෝල්ට්

2
N අනුපම්සයිනි ඔව්. සැබෑ යෙදුමක එවැනි පැකේජ නාමයක් තිබීම පිස්සු වනු ඇත.
ජේන්

3
එය පිස්සු වනු ඇත, කෙසේ වෙතත්, එය අනිෂ්ට නළුවෙකුට වැඩ කිරීමට ඉඩ සලසන ආකාරයේ උපකල්පනයකි. කවුරුහරි කියනවා "අනේ, අපි දන්නවා පන්ති කවදාවත් කුඩා අකුරු වලින් ආරම්භ නොවන බව / පැකේජ කිසි විටෙකත් අගනගර වලින් ආරම්භ නොවන බව". ඔබේ පංතියේ පැටවුමට ප්‍රවේශය ඇති අනිෂ්ට නළුවෙකුට දැනටමත් භයානක දේ කළ හැකි බව ඇත්තයි, එබැවින් එය අතිශය භයානක උපකල්පනයක් නොවේ.
corsiKa

2
IetPieterDeBie එසේ වන්නේ කෙසේද? ඔබ දැනගත යුතු වන්නේ ඔබට පරීක්ෂා කිරීමට අවශ්‍ය ක්‍රමයේ නම පමණි.
fool4jesus

20
ජාවා 8 එකතු කරන ලද getTypeName () ද ... ඒ සඳහා යාවත්කාලීන කිරීමට සැලකිලිමත්ද?
තියඩෝර් මර්ඩොක්

94

දේශීය පන්ති, ලැම්බඩා සහ 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()මඟින් සම්පාදකයා විසින් හඳුන්වා දුන් ඩොලර් සං signs ා තිත් මගින් ප්‍රතිස්ථාපනය කරයි.
  4. අරාව පංති සඳහා, සංරචක වර්ගයෙහි කැනොනිකල් නම නම් getCanonicalName()ක්‍රමය නැවත පැමිණේ . එසේ නොමැති නම්, එය පසුව සංරචක වර්ගයේ කැනොනිකල් නාමය ලබා දෙයි .nullnull[]

මෙම getSimpleName()ක්රමය:

  1. ඉහළ මට්ටමේ, කැදැලි, අභ්‍යන්තර සහ දේශීය පන්ති සඳහා, getSimpleName()ප්‍රභව ගොනුවේ ලියා ඇති පරිදි පන්තියේ නම නැවත ලබා දෙයි.
  2. නිර්නාමික පංති සඳහා getSimpleName()ප්‍රතිලාභ හිස් ය String.
  3. ලැම්බඩා පංති සඳහා , පැකේජයේ නම නොමැතිව ආපසු getSimpleName()එවිය යුතු දේ සාධාරණයි getName(). මෙය එතරම් තේරුමක් නැති අතර මට දෝෂයක් සේ පෙනේ, නමුත් getSimpleName()ආරම්භ කිරීමට ලැම්බඩා පන්තියක් කැඳවීමේ තේරුමක් නැත .
  4. අරාව පංති සඳහා getSimpleName()ක්‍රමය මඟින් සංරචක පන්තියේ සරල නම ලබා දෙයි []. නිර්නාමික පංතියක් වන සංරචක වර්ගය []ඔවුන්ගේ සරල නම් වලට සමාන වන විහිලු / අමුතු අතුරු ආබාධයකි .

2
… replacing the dollar-signs by dots: ප්‍රතිස්ථාපනය කරනු ලබන්නේ පරිසීමක ලෙස හඳුන්වා දුන් ඩොලර් සං signs ා පමණි. සරල නමක කොටසක් ලෙස ඔබට ඩොලර් තිබිය හැකි අතර ඒවා පවතිනු ඇත.
එම්වීජී

අපොයි! පන්ති නාමයේ කොටසක් ලෙස! මම පන්ති ට්‍රාන්ස්ෆෝමරයක් සංවර්ධනය කරමින් සිටින අතර, පන්තියේ සහ පැකේජයේ නම අතර ආරක්ෂිත පරිසීමකයක් වනු ඇතැයි මම සිතුවෙමි: /
හෝසේ රොබර්ටෝ අරාජෝ ජූනියර්

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
ඉහත පිළිතුරට සංස්කරණයක් යෝජනා කිරීම වඩා හොඳ නොවේ.
ලොකි

18

විවිධාකාර නම් කිරීමේ යෝජනා ක්‍රම නිසා මා ව්‍යාකූල වී ඇති අතර, මෙම ප්‍රශ්නය මෙහි දී මට හමු වූ විට මේ පිළිබඳව මගේම ප්‍රශ්නයක් ඇසීමට හා පිළිතුරු දීමට සූදානම්ව සිටියෙමි. මම හිතන්නේ මගේ සොයාගැනීම් එයට හොඳින් ගැලපෙන අතර දැනටමත් මෙහි ඇති දෙයට අනුපූරක වේ. මගේ අවධානය යොමු වී ඇත්තේ විවිධ යෙදුම් පිළිබඳ ලියකියවිලි සෙවීම සහ වෙනත් ස්ථානවල වර්ධනය විය හැකි තවත් අදාළ පද කිහිපයක් එකතු කිරීම ය.

පහත උදාහරණය සලකා බලන්න:

package a.b;
class C {
  static class D extends C {
  }
  D d;
  D[] ds;
}
  • මෙම සරල නමDකියන්නේ D. පංතිය ප්‍රකාශ කිරීමේදී ඔබ ලියූ කොටස එයයි. නිර්නාමික පංතිවලට සරල නමක් නොමැත. Class.getSimpleName()මෙම නම හෝ හිස් නූල ලබා දෙයි. ජේඑල්එස් 3.8 වගන්තියට අනුව හඳුනාගැනීමේ යන්ත්‍රයේ වලංගු කොටසක් වන බැවින් (එය තරමක් අධෛර්යමත් වුවද) සරල නමකට $ඔබ මේ ආකාරයෙන් ලිවුවහොත් එය අඩංගු විය හැකිය .$

  • අනුව 6.7 වන JLS කොටස , දෙකම 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$DD[La.b.C$D;D[]

  • මෙම පිළිතුරෙන් පෙන්නුම් කරන්නේ එකම පන්තියේ පැටවුම්කරු විසින් පටවන ලද පන්ති දෙකකට එකම කැනොනිකල් නමක් තිබිය හැකි නමුත් වෙනස් ද්විමය නම් තිබිය හැකි බවයි. අනෙකා විශ්වාසදායක ලෙස අඩු කිරීමට කිසිදු නමක් ප්‍රමාණවත් නොවේ: ඔබට කැනොනිකල් නාමයක් තිබේ නම්, නමේ කුමන කොටස් පැකේජ සහ පන්ති අඩංගු දැයි ඔබ නොදනී. ඔබට ද්විමය නාමයක් තිබේ නම්, $බෙදුම්කරුවන් ලෙස හඳුන්වා දුන් ඒවා සහ සරල නාමයක කොටසක් වූ ඒවා ඔබ දන්නේ නැත . (පන්ති ගොනුව ද්විමය නම ගබඩා කිරීම පන්තිය ම සහ එහි බහා පන්තියේ මෙම ධාවන කිරීමට ඉඩ සලසා දෙයි, මෙම වෙනස අවබෝධ .)

  • නිර්නාමික පංති සහ දේශීය පන්ති සඳහා පූර්ණ සුදුසුකම් සහිත නම් නොමැති නමුත් තවමත් ද්විමය නමක් ඇත. එවැනි පංති තුළ කූඩු කර ඇති පන්ති සඳහා ද එයම වේ. සෑම පන්තියකටම ද්විමය නමක් ඇත.

  • ධාවනය javap -v -privateමත a/b/C.classමෙම bytecode වර්ගය හඳුන්වන්නේ, දර්ශන dලෙස La/b/C$D;සහ අරා බව dsලෙස [La/b/C$D;. මේවා විස්තර කරන්නන් ලෙස හැඳින්වෙන අතර ඒවා JVMS 4.3 වගන්තියේ දක්වා ඇත .

  • a/b/C$Dමෙම විස්තර දෙකෙහිම භාවිතා වන පන්ති නාමය ද්විමය නාමයෙන් ප්‍රතිස්ථාපනය .කිරීමෙන් ඔබට ලැබෙනු ඇත /. ජේවීඑම් පිරිවිතරයෙන් මෙය ද්විමය නාමයේ අභ්‍යන්තර ස්වරූපය ලෙස පෙනේ . ජේවීඑම්එස් 4.2.1 වගන්තිය එය විස්තර කරන අතර ද්විමය නාමයෙන් වෙනස historical තිහාසික හේතූන් මත වූ බව සඳහන් කරයි.

  • මෙම ගොනුවේ නම සාමාන්ය ගොනු මත පදනම් පන්තිය කාරකයන් එක් පන්ති ඔබ අර්ථ නිරූපණය නම් දේ ඔබ ලබා ගන්න /නාමාවලියක් වෙන්කර ලෙස ද්වීමය නම අභ්යන්තර ස්වරූපයෙන්, සහ ගොනු නම් දිගුව ඇතුලත් .classඑය. ප්‍රශ්නාර්ථයෙන් පන්ති භාරකරු භාවිතා කරන පන්ති මාර්ගයට සාපේක්ෂව එය විසඳනු ලැබේ.


4
ජේඑල්එස් ගැන සඳහන් කර නිසි පාරිභාෂිතය භාවිතා කරන එකම පිළිතුර මෙය බැවින් පිළිගත් පිළිතුර විය යුතුය.
MEE

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

බයිට් කේතය ගතිකව පටවන මිශ්‍ර භාෂා පරිසරයන් හෝ පරිසරයන් සඳහා මෙය ගැටළුවක් විය හැකිය, උදා: යෙදුම් සේවාදායක සහ වෙනත් වේදිකා මෘදුකාංග.


2

getName () - මෙම පංති වස්තුව නියෝජනය කරන වස්තුවේ (පන්තිය, අතුරුමුහුණත, අරාව පන්තිය, ප්‍රාථමික වර්ගය හෝ අවලංගු කිරීම) නූලක් ලෙස ලබා දෙයි.

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()

ජාවා හි පන්ති නාමයක් ලබා ගැනීම ගැන වැඩි විස්තර දැනගැනීම සඳහා .


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.