Der Konstruktor-Rückgabetyp in Java

1. Übersicht

In diesem kurzen Tutorial konzentrieren wir uns auf den Rückgabetyp für einen Konstruktor in Java.

Zunächst werden wir uns mit der Funktionsweise der Objektinitialisierung in Java und der JVM vertraut machen. Dann werden wir tiefer gehen, um zu sehen, wie Objektinitialisierung und -zuweisung unter der Haube funktionieren.

2. Instanzinitialisierung

Beginnen wir mit einer leeren Klasse:

public class Color {}

Hier erstellen wir eine Instanz aus dieser Klasse und weisen sie einer Variablen zu:

Color color = new Color();

Nachdem Sie dieses einfache Java-Snippet kompiliert haben, werfen wir einen Blick auf seinen Bytecode mit dem Befehl javap -c :

0: new #7 // class Color 3: dup 4: invokespecial #9 // Method Color."":()V 7: astore_1

Wenn wir ein Objekt in Java instanziieren, führt die JVM die folgenden Operationen aus:

  1. Erstens findet es in seinem Prozessraum einen Platz für das neue Objekt.
  2. Anschließend führt die JVM den Systeminitialisierungsprozess durch. In diesem Schritt wird das Objekt in seinem Standardzustand erstellt. Der neue Opcode im Bytecode ist tatsächlich für diesen Schritt verantwortlich.
  3. Schließlich wird das Objekt mit dem Konstruktor und anderen Initialisierungsblöcken initialisiert. In diesem Fall ruft der aufrufende spezielle Opcode den Konstruktor auf.

Wie oben gezeigt, lautet die Methodensignatur für den Standardkonstruktor:

Method Color."":()V

Das ist der Name der Instanzinitialisierungsmethoden in der JVM . In diesem Fall ist dieist eine Funktion, die:

  • Nimmt nichts als Eingabe (leere Klammern nach dem Methodennamen)
  • gibt nichts zurück (V steht für void )

Daher ist der Rückgabetyp eines Konstruktors in Java und JVM ungültig.

Schauen Sie sich noch einmal unsere einfache Aufgabe an:

Color color = new Color();

Nachdem wir nun wissen, dass der Konstruktor void zurückgibt , wollen wir sehen, wie die Zuweisung funktioniert.

3. Wie die Zuordnung funktioniert

JVM ist eine stapelbasierte virtuelle Maschine. Jeder Stapel besteht aus Stapelrahmen. Einfach ausgedrückt entspricht jeder Stapelrahmen einem Methodenaufruf. Tatsächlich erstellt JVM Frames mit einem neuen Methodenaufruf und zerstört sie, wenn sie ihre Arbeit beenden:

Jeder Stapelrahmen verwendet ein Array zum Speichern lokaler Variablen und einen Operandenstapel zum Speichern von Teilergebnissen . Schauen wir uns vor diesem Hintergrund den Bytecode noch einmal an:

0: new #7 // class Color 3: dup 4: invokespecial #9 // Method Color."":()V 7: astore_1

So funktioniert die Zuordnung:

  • Die neue Anweisung erstellt eine Instanz von Color und überträgt ihre Referenz auf den Operandenstapel
  • Der dup- Opcode dupliziert das letzte Element auf dem Operandenstapel
  • Das Aufrufspezial nimmt die duplizierte Referenz und verwendet sie zur Initialisierung. Danach verbleibt nur noch die ursprüngliche Referenz auf dem Operandenstapel
  • Der astore_1 speichert den ursprünglichen Verweis auf Index 1 des Arrays lokaler Variablen. Das Präfix "a" bedeutet, dass das zu speichernde Element eine Objektreferenz ist und die "1" der Array-Index ist

Von nun an ist das zweite Element (Index 1) im Array der lokalen Variablen eine Referenz auf das neu erstellte Objekt . Daher verlieren wir die Referenz nicht und die Zuweisung funktioniert tatsächlich - auch wenn der Konstruktor nichts zurückgibt!

4. Fazit

In diesem kurzen Tutorial haben wir gelernt, wie die JVM unsere Klasseninstanzen erstellt und initialisiert. Darüber hinaus haben wir gesehen, wie die Instanzinitialisierung unter der Haube funktioniert.

Für ein noch detaillierteres Verständnis der JVM ist es immer eine gute Idee, ihre Spezifikation zu überprüfen.