Was ist das Class-Objekt (java.lang.Class)?

81

Die Java-Dokumentation für Classsagt:

ClassObjekte werden automatisch von der Java Virtual Machine beim Laden von Klassen und durch Aufrufe der defineClassMethode im Klassenladeprogramm erstellt.

Was sind diese ClassObjekte? Sind sie dieselben wie Objekte, die durch Aufrufen aus einer Klasse instanziiert wurden new?

object.getClass().getName()Wie kann zum Beispiel alles in eine Oberklasse typisiert werden Class, auch wenn ich nicht erbe java.lang.Class?

Karbonisator
quelle

Antworten:

97

Nichts wird typisiert Class. Jeder Objectin Java gehört zu einem bestimmten class. Deshalb definiert die ObjectKlasse, die von allen anderen Klassen geerbt wird, die getClass()Methode.

getClass()oder das Klassenliteral - Foo.classGeben Sie ein ClassObjekt zurück, das einige Metadaten zur Klasse enthält:

  • Name
  • Paket
  • Methoden
  • Felder
  • Konstruktoren
  • Anmerkungen

und einige nützliche Methoden wie Gießen und verschiedene Prüfungen ( isAbstract(), isPrimitive()usw.). Das Javadoc zeigt genau, welche Informationen Sie über eine Klasse erhalten können.

Wenn beispielsweise einer Ihrer Methoden ein Objekt zugewiesen wurde und Sie es verarbeiten möchten, falls es mit der @ProcessableAnmerkung versehen ist, gilt Folgendes :

public void process(Object obj) {
    if (obj.getClass().isAnnotationPresent(Processable.class)) {
       // process somehow; 
    }
}

In diesem Beispiel erhalten Sie die Metadaten zur Klasse des angegebenen Objekts (was auch immer es ist) und prüfen, ob es eine bestimmte Anmerkung enthält. Viele der Methoden in einer ClassInstanz werden als "Reflexionsoperationen" oder einfach als "Reflexion" bezeichnet. Lesen Sie hier mehr über Reflexion, warum und wann sie verwendet wird.

Beachten Sie auch, dass das ClassObjekt Aufzählungen und Schnittstellen zusammen mit Klassen in einer laufenden Java-Anwendung darstellt und über die entsprechenden Metadaten verfügt.

Zusammenfassend lässt sich sagen, dass jedes Objekt in Java eine Klasse hat (zu dieser gehört) und über ein entsprechendes ClassObjekt verfügt, das Metadaten darüber enthält, auf die zur Laufzeit zugegriffen werden kann.

Bozho
quelle
37
Und es macht Spaß, weiter darüber nachzudenken. Die ClassKlasse erbt von sich Objectselbst. Class.classGibt ein ClassObjekt zurück, das die ClassKlasse darstellt. Sie können über Reflexion nachdenken. MEIN KOPF ASPLODE.
CDhowie
1
@pst: Ich habe. Ich möchte Menschen verletzen. Jede Sprache / jedes Framework mit so vielen Methoden im Stammtyp verdient es, begraben zu werden. Es hat PHP-Stil Tack-Random-Crap-auf-die-API-ohne-Voraussicht-Syndrom. Cue die Flammen ...
cdhowie
1
Klasse c1 = Fahrzeugklasse; Was ist diese "Klasse"? Ist es eine öffentliche Variable, die in jeder Klasse existiert?
David Blaine
1
In gewisser Weise ja. Tatsächlich ist es ein "Klassenliteral" - so verweisen Sie auf das Class-Objekt mit Namen.
Bozho
1
@cdhowie Dein Kommentar hat das Wort 'Klasse' für mich semantisch gesättigt.
Stillanoob
44

Ein Klassenobjekt ist eine Art Metaobjekt, das die Klasse eines Objekts beschreibt. Es wird hauptsächlich mit den Reflexionsfunktionen von Java verwendet. Sie können es sich wie eine "Blaupause" der tatsächlichen Klasse vorstellen. ZB hast du ein Klasse Auto wie dieses:

public class Car {
    public String brand;
}

Sie können dann ein Klassenobjekt erstellen, das Ihre "Auto" -Klasse beschreibt.

Class myCarClass = Class.forName("Car");

Jetzt können Sie alle Arten von Abfragen für Ihre Auto-Klasse für dieses Klassenobjekt durchführen:

myCarClass.getName() - returns "Car"
myCarClass.getDeclaredField("brand") - returns a Field object describing the "brand" field

und so weiter. Jedes Java-Objekt verfügt über eine Methode getClass (), die das Class-Objekt zurückgibt, das die Klasse des Java-Objekts beschreibt. Sie könnten also so etwas tun:

Car myCar = new Car();
Class myCarClass  = myCar.getClass();

Dies funktioniert auch für Objekte, die Sie nicht kennen, z. B. Objekte, die Sie von außen erhalten:

public void tellMeWhatThisObjectsClassIs(Object obj) {
    System.out.println(obj.getClass().getName());
}

Sie können diese Methode mit jedem Java-Objekt füttern und es wird die tatsächliche Klasse des Objekts gedruckt, das Sie ihm gegeben haben.

Wenn Sie mit Java arbeiten, müssen Sie sich die meiste Zeit nicht um Klassenobjekte kümmern. Sie haben jedoch einige praktische Anwendungsfälle. Mit ihnen können Sie beispielsweise Objekte einer bestimmten Klasse programmgesteuert instanziieren, was häufig für die Serialisierung und Deserialisierung von Objekten verwendet wird (z. B. das Hin- und Herkonvertieren von Java-Objekten in / von XML oder JSON).

Class myCarClass = Class.forName("Car");
Car myCar = myCarClass.newInstance();  // is roughly equivalent to = new Car();

Sie können es auch verwenden, um alle deklarierten Felder oder Methoden Ihrer Klasse usw. herauszufinden, was in bestimmten Fällen sehr nützlich ist. Wenn Ihre Methode beispielsweise ein unbekanntes Objekt erhält und Sie mehr darüber wissen müssen, z. B. wenn es eine Schnittstelle usw. implementiert, ist die Klassenklasse hier Ihr Freund.

Kurz gesagt, mit den Klassen Class, Field, Method usw. im Paket java.lang.reflect können Sie Ihre definierten Klassen, Methoden und Felder analysieren, neue Instanzen davon erstellen und Methoden aller Art aufrufen und sie ermöglichen es Ihnen, dies zur Laufzeit dynamisch zu tun.

Jan Thomä
quelle
1
Klasse c1 = Fahrzeugklasse; Was ist diese "Klasse"? Ist es eine öffentliche Variable, die in jeder Klasse existiert?
David Blaine
5
Es ist im Grunde syntaktischer Zucker. Es ist etwas, das der Compiler als etwas auswertet, das das Klassenobjekt mit dem angegebenen Namen lädt. Entspricht in etwa Class.forName ("vollständig qualifizierter Klassenname"), es wird jedoch überprüft, ob die Klasse zur Kompilierungszeit vorhanden ist, während Class.forName () zur Laufzeit ausgeführt wird.
Jan Thomä
8

getClass()ist eine Methode, die ein Objekt zurückgibt , das eine Instanz von java.lang.Class... ist. Es ist kein Casting beteiligt. Casting würde so aussehen:

Class<?> type = (Class<?>) object;
ColinD
quelle
6

Ich möchte auch zu ColinDs Antwort hinzufügen, dass getClass dasselbe Objekt für Instanzen desselben Typs zurückgibt . Dies wird wahr gedruckt :

    MyOtherClass foo = new MyOtherClass();
    MyOtherClass bar = new MyOtherClass();
    System.out.println(foo.getClass()==bar.getClass());

Beachten Sie, dass dies nicht der Fall ist equals, den ich verwende ==.

Koray Tugay
quelle
3

Ein Class-Objekt ist eine Instanz von Class (java.lang.Class). Das folgende Zitat aus dem Javadoc der Klasse sollte Ihre Frage beantworten

Klasse hat keinen öffentlichen Konstruktor. Stattdessen werden Klassenobjekte automatisch von der Java Virtual Machine beim Laden von Klassen und durch Aufrufe der defineClass-Methode im Klassenladeprogramm erstellt.

Pakka Techie
quelle
2

Um das Klassenobjekt vollständig zu verstehen, lassen Sie uns zurückgehen und verstehen, dass wir das Klassenobjekt überhaupt erhalten. Sie sehen, jede .javaDatei, die Sie erstellen, wenn Sie diese .javaDatei kompilieren, erstellt die JVM eine .classDatei. Diese Datei enthält alle Informationen über die Klasse, nämlich:

  1. Vollqualifizierter Name der Klasse
  2. Eltern der Klasse
  3. Methodeninformationen
  4. Variable Felder
  5. Konstrukteur
  6. Modifikatorinformationen
  7. Ständiger Pool

Die Liste, die Sie oben sehen, ist die, die Sie normalerweise in einer typischen Klasse sehen. Bis zu diesem Punkt befinden sich Ihre .javaDatei und Ihre Datei .classauf Ihrer Festplatte. Wenn Sie tatsächlich die Klasse verwenden müssen, dh Code in der main()Methode ausführen , verwendet die JVM diese .classDatei auf Ihrer Festplatte und lädt sie in einen von 5 Speichern Bereiche in jvm, dem Methodenbereich, unmittelbar nach dem Laden der .classDatei in den Methodenbereich verwendet der jvm diese Informationen und ein Klassenobjekt, das die im Heapspeicherbereich vorhandene Klasse darstellt .

Hier ist die Ansicht der obersten Ebene:

.java--compile -> .class-> wenn Sie Ihr Skript ausführen -> .classwird in den Methodenbereich geladen --jvm erstellt ein Klassenobjekt aus dem Methodenbereich -> ein Klassenobjekt wird geboren

Mit einem Klassenobjekt erhalten Sie Informationen wie Klassennamen und Methodennamen, alles über die Klasse.

Beachten Sie außerdem, dass für jede Klasse, die Sie im Skript verwenden, nur ein Klassenobjekt vorhanden sein darf.

Hoffe das macht Sinn

Brendon Cheung
quelle
gute zusätzliche Punkte. Eine Bemerkung zum Wortlaut: Ich kenne kein Thema, das sich gut bearbeiten lässt. "Das JVM verwendet diese Informationen und ein Klassenobjekt , das die Klasse darstellt , die im Heap-Speicherbereich vorhanden ist." sieht nicht korrekt aus, Zeile später mit -> sieht logischer aus. Bin ich hier richtig Bitte machen Sie konsequent, danke!
Alexei Martianov
1

Die Object-Klasse ist standardmäßig die übergeordnete Klasse aller Klassen in Java. Mit anderen Worten, es ist die oberste Klasse von Java.

Die Object-Klasse ist nützlich, wenn Sie auf ein Objekt verweisen möchten, dessen Typ Sie nicht kennen. Beachten Sie, dass die Referenzvariable der übergeordneten Klasse auf das untergeordnete Klassenobjekt verweisen kann, das als Upcasting bezeichnet wird.

Nehmen wir ein Beispiel: Es gibt eine getObject () -Methode, die ein Objekt zurückgibt. Sie kann jedoch von einem beliebigen Typ wie Employee, Student usw. sein. Wir können die Objektklassenreferenz verwenden, um auf dieses Objekt zu verweisen. Zum Beispiel:

Object obj=getObject(); // Wir wissen nicht, welches Objekt von dieser Methode zurückgegeben wird

Ishanka Abeysinghe
quelle