Was ist der Unterschied zwischen kanonischem Namen, einfachem Namen und Klassennamen in Java Class?

973

Was ist in Java der Unterschied zwischen diesen:

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

Ich habe das Javadoc mehrmals überprüft und dies erklärt es nie gut. Ich habe auch einen Test durchgeführt, der keine wirkliche Bedeutung für die Art und Weise hatte, wie diese Methoden aufgerufen werden.

Mohamed Taher Alrefaie
quelle
218
Ich denke, das ist eine vernünftige Frage. Der Javadoc kann den Unterschied zwischen den drei nicht gut erklären.
Graham Borland
1
Siehe - docs.oracle.com/javase/6/docs/api/java/lang/Class.html oder schreiben Sie einfach einen Test.
Nick Holt
7
@GrahamBorland Der Javadoc sagt "wie in der Java-Sprachspezifikation definiert" - damit Sie es in diesem Dokument nachschlagen können. Nur weil es sich nicht um einen anklickbaren Link handelt, können Benutzer mit minimalem Aufwand auf das erste Suchmaschinenergebnis klicken.
Vbence
66
@vbence: Die meisten Leute würden lieber Dinge erledigen, als im JLS nach trivialen Dingen wie diesen zu suchen. Daher ist dies das erste Google-Ergebnis :)
Pathikrit

Antworten:

1130

Wenn Sie sich bei etwas nicht sicher sind, schreiben Sie zuerst einen Test.

Ich war das:

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

Drucke:

int.class (primitiv):
    getName (): int
    getCanonicalName (): int
    getSimpleName (): int
    getTypeName (): int

String.class (gewöhnliche Klasse):
    getName (): java.lang.String
    getCanonicalName (): java.lang.String
    getSimpleName (): String
    getTypeName (): java.lang.String

java.util.HashMap.SimpleEntry.class (verschachtelte Klasse):
    getName (): java.util.AbstractMap $ SimpleEntry
    getCanonicalName (): java.util.AbstractMap.SimpleEntry
    getSimpleName (): SimpleEntry
    getTypeName (): java.util.AbstractMap $ SimpleEntry

new java.io.Serializable () {}. getClass () (anonyme innere Klasse):
    getName (): ClassNameTest $ 1
    getCanonicalName (): null
    getSimpleName ():    
    getTypeName (): ClassNameTest $ 1

Im letzten Block befindet sich ein leerer Eintrag, in dem getSimpleNameeine leere Zeichenfolge zurückgegeben wird.

Das Ergebnis ist:

  • Der Name ist der Name, mit dem Sie die Klasse dynamisch laden möchten, z. B. mit einem Aufruf Class.forNamemit der Standardeinstellung ClassLoader. Im Rahmen eines bestimmten ClassLoaderhaben alle Klassen eindeutige Namen.
  • Der kanonische Name ist der Name, der in einer Importanweisung verwendet wird. Dies kann während toStringoder während der Protokollierung hilfreich sein . Wenn der javacCompiler die vollständige Ansicht eines Klassenpfads hat, erzwingt er die Eindeutigkeit der darin enthaltenen kanonischen Namen, indem er beim Kompilieren vollständig qualifizierte Klassen- und Paketnamen in Konflikt bringt. JVMs müssen jedoch solche Namenskonflikte akzeptieren, und daher identifizieren kanonische Namen Klassen innerhalb von a nicht eindeutig ClassLoader. (Im Nachhinein wäre ein besserer Name für diesen Getter gewesen getJavaName; diese Methode stammt jedoch aus einer Zeit, als die JVM ausschließlich zum Ausführen von Java-Programmen verwendet wurde.)
  • Der einfache Name identifiziert die Klasse lose, kann wiederum während toStringoder bei Protokollierungsvorgängen nützlich sein , ist jedoch nicht garantiert eindeutig.
  • Der Typname gibt "eine informative Zeichenfolge für den Namen dieses Typs" zurück, "Es ist wie toString (): Es ist rein informativ und hat keinen Vertragswert" (wie von sir4ur0n geschrieben).
Nick Holt
quelle
5
Welches Extra wird Ihrer Meinung nach benötigt?
Nick Holt
2
@ AnupamSaini ja. Einen solchen Paketnamen in einer echten Anwendung zu haben, wäre verrückt.
Jayen
3
IT wäre verrückt, aber das ist die Art von Annahme, die es einem böswilligen Schauspieler ermöglichen würde, zu arbeiten. Jemand sagt: "Oh, wir wissen, dass der Unterricht niemals mit Kleinbuchstaben / Paketen beginnen wird, niemals mit Großbuchstaben." Zugegeben, ein böswilliger Schauspieler, der Zugriff auf Ihren Klassenlader hat, kann bereits schreckliche Dinge tun, daher ist dies wahrscheinlich keine absolut schreckliche Annahme.
CorsiKa
2
@PieterDeBie Wie so? Sie müssen lediglich den Methodennamen kennen, den Sie testen möchten.
narr4jesus
20
Java 8 hat auch getTypeName () hinzugefügt. Möchten Sie das aktualisieren?
Theodore Murdock
90

Hinzufügen lokaler Klassen, Lambdas und der toString()Methode zum Vervollständigen der beiden vorherigen Antworten. Außerdem füge ich Arrays von Lambdas und Arrays anonymer Klassen hinzu (die in der Praxis jedoch keinen Sinn ergeben):

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 {}

Dies ist die vollständige Ausgabe:

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;

Also, hier sind die Regeln. Beginnen wir zunächst mit primitiven Typen und void:

  1. Wenn das Klassenobjekt einen primitiven Typ darstellt oder void, geben alle vier Methoden einfach seinen Namen zurück.

Nun die Regeln für die getName()Methode:

  1. Jede Nicht-Lambda- und Nicht-Array-Klasse oder -Schnittstelle (dh oberste Ebene, verschachtelt, inner, lokal und anonym) hat einen Namen (der von zurückgegeben wird getName()), bei dem es sich um den Paketnamen handelt, gefolgt von einem Punkt (falls ein Paket vorhanden ist) ), gefolgt vom Namen der vom Compiler generierten Klassendatei (ohne Suffix .class). Wenn es kein Paket gibt, ist es einfach der Name der Klassendatei. Wenn die Klasse eine innere, verschachtelte, lokale oder anonyme Klasse ist, sollte der Compiler mindestens eine $in seinem Klassendateinamen generieren . Beachten Sie, dass bei anonymen Klassen der Klassenname mit einem Dollarzeichen gefolgt von einer Zahl endet.
  2. Lambda-Klassennamen sind im Allgemeinen unvorhersehbar, und Sie sollten sich sowieso nicht darum kümmern. Genau, ihr Name ist der Name der einschließenden Klasse, gefolgt von $$Lambda$einer Zahl, gefolgt von einem Schrägstrich, gefolgt von einer anderen Zahl.
  3. Der Klassendeskriptors der Primitiven sind Zfür boolean, Bfür byte, Sfür short, Cfür char, Ifür int, Jfür long, Ffür floatund Dfür double. Bei Nicht-Array-Klassen und -Schnittstellen Lfolgt auf den Klassendeskriptor das, was getName()gefolgt von gefolgt wird ;. Bei Array-Klassen [folgt auf den Klassendeskriptor der Klassendeskriptor des Komponententyps (der selbst eine andere Array-Klasse sein kann).
  4. Für Array-Klassen gibt die getName()Methode ihren Klassendeskriptor zurück. Diese Regel scheint nur für Array-Klassen fehlzuschlagen, deren Komponententyp ein Lambda ist (was möglicherweise ein Fehler ist), aber hoffentlich sollte dies sowieso keine Rolle spielen, da selbst die Existenz von Array-Klassen, deren Komponententyp ein Lambda ist, keinen Sinn macht.

Nun die toString()Methode:

  1. Wenn die Klasseninstanz eine Schnittstelle darstellt (oder eine Anmerkung, bei der es sich um einen speziellen Schnittstellentyp handelt), wird toString()zurückgegeben "interface " + getName(). Wenn es ein Grundelement ist, kehrt es einfach zurück getName(). Wenn es etwas anderes ist (ein Klassentyp, auch wenn es ein ziemlich seltsamer Typ ist), kehrt er zurück "class " + getName().

Die getCanonicalName()Methode:

  1. Bei Klassen und Schnittstellen der obersten Ebene gibt die getCanonicalName()Methode genau das zurück, was die getName()Methode zurückgibt.
  2. Die getCanonicalName()Methode gibt nullfür anonyme oder lokale Klassen und für Array-Klassen dieser Klassen zurück.
  3. Für innere und verschachtelte Klassen und Schnittstellen gibt die getCanonicalName()Methode zurück, was die getName()Methode die vom Compiler eingeführten Dollarzeichen durch Punkte ersetzen würde.
  4. Für Array-Klassen gibt die getCanonicalName()Methode zurück, nullwenn der kanonische Name des Komponententyps lautet null. Andernfalls wird der kanonische Name des Komponententyps zurückgegeben, gefolgt von [].

Die getSimpleName()Methode:

  1. Für verschachtelte, innere und lokale Klassen der obersten Ebene getSimpleName()gibt der den Namen der Klasse zurück, wie er in der Quelldatei geschrieben ist.
  2. Für anonyme Klassen wird getSimpleName()eine leere zurückgegeben String.
  3. Für Lambda-Klassen gibt das getSimpleName()nur das zurück, was getName()ohne den Paketnamen zurückgegeben werden würde. Das macht nicht viel Sinn und sieht für mich wie ein Fehler aus, aber es macht keinen Sinn, zunächst getSimpleName()eine Lambda-Klasse aufzurufen .
  4. Für Array-Klassen gibt die getSimpleName()Methode den einfachen Namen der Komponentenklasse zurück, gefolgt von []. Dies hat den lustigen / seltsamen Nebeneffekt, dass Array-Klassen, deren Komponententyp eine anonyme Klasse ist, genauso []einfache Namen haben.
Victor Stafusa
quelle
2
… replacing the dollar-signs by dots: Nur die als Trennzeichen eingeführten Dollarzeichen werden ersetzt. Sie können Dollars als Teil eines einfachen Namens haben, und diese bleiben an Ort und Stelle.
MvG
Ach nein! Als Teil des Klassennamens! Ich entwickle einen Klassentransformator und dachte, dass '/' ein sicheres Trennzeichen zwischen der Klasse und dem Paketnamen sein würde: /
José Roberto Araújo Júnior
81

Zusätzlich zu den Beobachtungen von Nick Holt habe ich einige Fälle für den ArrayDatentyp ausgeführt:

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

Über Code-Snippet druckt:

[I
int[]
int[]

[Ljava.lang.Integer;
java.lang.Integer[]
Integer[]
gerardw
quelle
28
Es wäre nicht viel besser, eine Änderung der obigen Antwort vorzuschlagen.
LoKi
17

Ich war auch verwirrt über die Vielzahl der verschiedenen Namensschemata und wollte gerade meine eigene Frage dazu stellen und beantworten, als ich diese Frage hier fand. Ich denke, meine Ergebnisse passen gut genug und ergänzen das, was bereits hier ist. Mein Fokus liegt auf der Suche nach Dokumentation zu den verschiedenen Begriffen und dem Hinzufügen weiterer verwandter Begriffe, die an anderen Stellen auftauchen könnten.

Betrachten Sie das folgende Beispiel:

package a.b;
class C {
  static class D extends C {
  }
  D d;
  D[] ds;
}
  • Der einfache Name von Dist D. Das ist nur der Teil, den Sie geschrieben haben, als Sie die Klasse deklariert haben. Anonyme Klassen haben keinen einfachen Namen. Class.getSimpleName()Gibt diesen Namen oder die leere Zeichenfolge zurück. Es ist möglich, dass der einfache Name ein enthält, $wenn Sie ihn so schreiben, da er $ein gültiger Teil eines Bezeichners gemäß JLS-Abschnitt 3.8 ist (auch wenn er etwas entmutigt ist).

  • Gemäß dem JLS-Abschnitt 6.7 wären beide a.b.C.Dund vollständig qualifizierte Namen , aber nur der kanonische Name von . Jeder kanonische Name ist also ein vollständig qualifizierter Name, aber das Gegenteil ist nicht immer der Fall. gibt den kanonischen Namen zurück oder .a.b.C.D.D.Da.b.C.DDClass.getCanonicalName()null

  • Class.getName()wird dokumentiert, um den Binärnamen zurückzugeben , wie in JLS-Abschnitt 13.1 angegeben . In diesem Fall wird a.b.C$Dfür Dund [La.b.C$D;für zurückgegeben D[].

  • Diese Antwort zeigt, dass zwei Klassen, die von demselben Klassenlader geladen werden, denselben kanonischen Namen, aber unterschiedliche Binärnamen haben können . Keiner der beiden Namen reicht aus, um den anderen zuverlässig abzuleiten: Wenn Sie den kanonischen Namen haben, wissen Sie nicht, welche Teile des Namens Pakete sind und welche Klassen enthalten. Wenn Sie den Binärnamen haben, wissen Sie nicht, welche $als Trennzeichen eingeführt wurden und welche Teil eines einfachen Namens waren. (In der Klassendatei werden der Binärname der Klasse selbst und ihre umschließende Klasse gespeichert , sodass die Laufzeit diese Unterscheidung treffen kann .)

  • Anonyme Klassen und lokale Klassen haben keine vollständig qualifizierten Namen, aber dennoch einen Binärnamen . Gleiches gilt für Klassen, die in solchen Klassen verschachtelt sind. Jede Klasse hat einen binären Namen.

  • Das Ausführen javap -v -privatevon a/b/C.classzeigt, dass sich der Bytecode auf den Typ von das La/b/C$D;und den des Arrays dsals bezieht [La/b/C$D;. Diese werden als Deskriptoren bezeichnet und sind in Abschnitt 4.3 von JVMS angegeben .

  • Der a/b/C$Din diesen beiden Deskriptoren verwendete Klassenname wird durch Ersetzen .durch /den Binärnamen erhalten. Die JVM-Spezifikation nennt dies anscheinend die interne Form des Binärnamens . JVMS-Abschnitt 4.2.1 beschreibt es und gibt an, dass der Unterschied zum Binärnamen aus historischen Gründen bestand.

  • Der Dateiname einer Klasse in einem der typischen auf Dateinamen basierenden Klassenladeprogramme wird angezeigt, wenn Sie den Dateinamen /in der internen Form als Verzeichnistrennzeichen interpretieren und die Dateinamenerweiterung .classan ihn anhängen . Es wird relativ zum Klassenpfad aufgelöst, der vom betreffenden Klassenlader verwendet wird.

MvG
quelle
3
Dies sollte die akzeptierte Antwort sein, da dies die einzige Antwort ist, die auf das JLS verweist und die richtigen Terminologien verwendet.
John
10

Dies ist das beste Dokument, das ich gefunden habe, um getName (), getSimpleName (), getCanonicalName () zu beschreiben.

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[]
Kiran
quelle
3

Es ist interessant zu bemerken, dass getCanonicalName()und getSimpleName()kann erhöhen, InternalErrorwenn der Klassenname fehlerhaft ist. Dies geschieht für einige Nicht-Java-JVM-Sprachen, z. B. Scala.

Beachten Sie Folgendes (Scala 2.11 unter Java 8):

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

Dies kann ein Problem für Umgebungen mit gemischten Sprachen oder Umgebungen sein, in denen Bytecode dynamisch geladen wird, z. B. App-Server und andere Plattformsoftware.

Sim
quelle
2

getName () - Gibt den Namen der Entität (Klasse, Schnittstelle, Array-Klasse, primitiver Typ oder void), die von diesem Class-Objekt dargestellt wird, als String zurück.

getCanonicalName () - gibt den kanonischen Namen der zugrunde liegenden Klasse zurück, wie in der Java-Sprachspezifikation definiert.

getSimpleName () - gibt den einfachen Namen der zugrunde liegenden Klasse zurück, dh den Namen, den sie im Quellcode angegeben hat.

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 
  }
}

Ein Unterschied besteht darin, dass Sie bei Verwendung einer anonymen Klasse einen Nullwert erhalten können, wenn Sie versuchen, den Namen der Klasse mithilfe von zu ermittelngetCanonicalName()

Eine andere Tatsache ist, dass sich die getName()Methode anders verhält als die getCanonicalName()Methode für innere Klassen . getName()verwendet einen Dollar als Trennzeichen zwischen dem kanonischen Namen der umschließenden Klasse und dem einfachen Namen der inneren Klasse.

Weitere Informationen zum Abrufen eines Klassennamens in Java .

Abdul Alim Shakir
quelle
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
Shirish Singh
quelle
1
Die ersten beiden Zeilen innerhalb der Methode können aufClass<StringBuffer> clazz = StringBuffer.class
ThePyroEagle