Zweifel in Java-Grundlagen?

8
%Vor%

im obigen Code, warum ist die Anweisung innerhalb der geschweiften Klammern ((d. ​​h.) "Hai") gedruckt, bevor der Konstruktor ausgeführt wird.

    
Hariharbalaji 12.12.2009, 12:31
quelle

4 Antworten

32

Lassen Sie es mit einem klareren Beispiel ausdrücken:

%Vor%

und teste es wie folgt:

%Vor%

Ausgabe:

%Vor%

Die statischen Initialisierer werden nur während der Laufzeit einmal ausgeführt, insbesondere während des Ladens der Klasse. Die Instanzinitialisierer werden bei jeder Instanziierung vor dem Konstruktor ausgeführt.

Sie können mehr als eine davon haben und sie werden in der Reihenfolge ausgeführt, wie sie in der Codierung erscheinen.

Der Hauptvorteil von Instanzinitialisierungen besteht darin, dass sie unabhängig davon ausgeführt werden, welchen Konstruktor Sie verwenden. Sie gelten für jeden von ihnen, sodass Sie die allgemeine Initialisierung nicht für alle duplizieren müssen.

Der Hauptvorteil von statischen Initialisierern besteht darin, dass sie nur einmal während des Ladens der Klasse ausgeführt werden. Ein bekanntes Beispiel aus der realen Welt ist der JDBC-Treiber. Wenn du es tust

%Vor%

die nur die static Initialisierer ausführt, dann wird jeder (anständige) JDBC Treiber sich in DriverManager wie folgt registrieren

%Vor%

Auf diese Weise kann DriverManager den richtigen JDBC-Treiber während getConnection() finden.

    
BalusC 12.12.2009, 12:50
quelle
5

Ja. Es ist ein Instanzinitialisierer . Es wird ausgeführt, sobald die Klasse instanziiert wird.

    
Bombe 12.12.2009 12:33
quelle
3
  

Im obigen Code ist es so, dass die Anweisung innerhalb der geschweiften Klammern ((d. ​​h.) "Hai") gedruckt wird, bevor der Konstruktor ausgeführt wird.

Dies ist das erwartete Verhalten, wie im Abschnitt 12.5 Erstellung von Neu beschrieben Klasseninstanzen der Java-Sprachspezifikation :)

  

Kurz vor einer Referenz auf die neu   Das erstellte Objekt wird als zurückgegeben   Ergebnis ist der angegebene Konstruktor   verarbeitet, um das neue Objekt zu initialisieren   Verwenden Sie das folgende Verfahren:

     
  1. Weisen Sie dem neu erstellten Parameter die Argumente für den Konstruktor zu   Variablen für diesen Konstruktor   Aufruf.
  2.   
  3. Wenn dieser Konstruktor mit einem expliziten Konstruktoraufruf von beginnt   ein anderer Konstruktor in derselben Klasse   (mit this ), dann werte die   Argumente und verarbeiten diesen Konstruktor   Aufruf rekursiv mit diesen   dieselben fünf Schritte. Wenn dieser Konstruktor   Der Aufruf wird dann abrupt beendet   Dieser Vorgang endet abrupt für   der gleiche Grund; andernfalls, fahre fort   mit Schritt 5.
  4.   
  5. Dieser Konstruktor beginnt nicht mit einem expliziten Konstruktor   Aufruf eines anderen Konstruktors in   die gleiche Klasse (mit this ). Wenn das ist   Konstruktor ist für eine andere Klasse als    Object , dann wird dieser Konstruktor   Beginne mit einem expliziten oder impliziten   Aufruf eines Superklassenkonstruktors   (mit super ). Bewerten   Argumente und verarbeiten diese Oberklasse   Konstruktoraufruf rekursiv   mit den gleichen fünf Schritten. Wenn das   Der Konstruktoraufruf wird abgeschlossen   abrupt, dann dieses Verfahren   schließt abrupt für dasselbe ab   Grund. Andernfalls fahren Sie mit Schritt fort   4.
  6.   
  7. Führt die Instanzinitialisierer und Instanzvariableninitialisierer für aus   Diese Klasse weist die Werte von   Instanzvariable Initialisierer zum   entsprechende Instanzvariablen, in   die Reihenfolge von links nach rechts, in der sie   erscheinen im Quellcode textuell   für die Klasse. Wenn die Ausführung eines der   Diese Initiatoren führen zu einem   Ausnahme, dann nicht weiter   Initialisierer werden verarbeitet und dies   Das Verfahren endet damit abrupt   gleiche Ausnahme. Ansonsten, fahre fort   mit Schritt 5. (In einigen frühen   Implementierungen, der Compiler   fälschlicherweise den Code weggelassen   initialisiere ein Feld wenn das Feld   Initialisiererausdruck war eine Konstante   Ausdruck, dessen Wert gleich war   der Standardinitialisierungswert für   sein Typ.)
  8.   
  9. Führe den Rest des Rumpfes dieses Konstruktors aus. Wenn diese Ausführung   schließt abrupt, dann das   Das Verfahren endet abrupt für die   gleicher Grund. Ansonsten, diese Prozedur   normal abgeschlossen.
  10.   

Weitere Informationen über den Abschnitt 8.6 Instance Initiators finden Sie hier. .Instance-Initialisierer.

    
Pascal Thivent 12.12.2009 23:44
quelle
2

Klammern direkt innerhalb einer Klasse führen einen Instanzinitialisierer ein (eingeführt in Java 1.1). Sie werden ähnlich wie Code behandelt, um Felder zuzuweisen, die als Teil der Deklaration geschrieben wurden. Das Folgende ist also gleichwertig:

%Vor%

und

%Vor%

Der Code wird von Konstruktoren sofort nach dem Aufruf eines Super-Konstruktors ausgeführt. Wenn also keine andere Initialisierung vorgenommen wird, kann der Code äquivalent als Teil des Konstruktors geschrieben werden:

%Vor%

Klammern an der gleichen Position, denen das Schlüsselwort static und die statischen Initialisierer vorangestellt sind, werden bei der Initialisierung einer Klasse einmal ausgeführt, nicht pro Instanz.

    
Tom Hawtin - tackline 12.12.2009 12:54
quelle

Tags und Links