Dies ist direkt von http://www.programcreek.com/2011/10/java-class-instance-initializers/
1. Ausführungsreihenfolge
Schauen Sie sich die folgende Klasse an. Wissen Sie, welche zuerst ausgeführt wird?
public class Foo {
//instance variable initializer
String s = "abc";
//constructor
public Foo() {
System.out.println("constructor called");
}
//static initializer
static {
System.out.println("static initializer called");
}
//instance initializer
{
System.out.println("instance initializer called");
}
public static void main(String[] args) {
new Foo();
new Foo();
}
}
Ausgabe:
statischer Initialisierer aufgerufen
Instanzinitialisierer aufgerufen
Konstruktor aufgerufen
Instanzinitialisierer aufgerufen
Konstruktor aufgerufen
2. Wie funktioniert der Java-Instanzinitialisierer?
Der obige Instanzinitialisierer enthält eine println-Anweisung. Um zu verstehen, wie es funktioniert, können wir es als variable Zuweisungsanweisung behandeln, z b = 0
. Dies kann das Verständnis offensichtlicher machen.
Anstatt
int b = 0
, du könntest schreiben
int b;
b = 0;
Daher sind Instanzinitialisierer und Instanzvariableninitialisierer ziemlich gleich.
3. Wann sind Instanzinitialisierer nützlich?
Die Verwendung von Instanzinitialisierern ist selten, kann jedoch eine nützliche Alternative zu Instanzvariableninitialisierern sein, wenn:
- Der Initialisierungscode muss Ausnahmen behandeln
- Führen Sie Berechnungen durch, die mit einem Instanzvariableninitialisierer nicht ausgedrückt werden können.
Natürlich könnte ein solcher Code in Konstruktoren geschrieben werden. Wenn eine Klasse jedoch mehrere Konstruktoren hätte, müssten Sie den Code in jedem Konstruktor wiederholen.
Mit einem Instanzinitialisierer können Sie den Code nur einmal schreiben. Er wird ausgeführt, unabhängig davon, mit welchem Konstruktor das Objekt erstellt wird. (Ich denke, dies ist nur ein Konzept und es wird nicht oft verwendet.)
Ein weiterer Fall, in dem Initialisierer nützlich sind, sind anonyme innere Klassen, die überhaupt keine Konstruktoren deklarieren können. (Ist dies ein guter Ort, um eine Protokollierungsfunktion zu platzieren?)
Danke an Derhein.
Beachten Sie auch, dass anonyme Klassen, die Schnittstellen [1] implementieren, keine Konstruktoren haben. Daher werden Instanzinitialisierer benötigt, um alle Arten von Ausdrücken zur Konstruktionszeit auszuführen.
public static void staticMethod(){}
, wenn Sie ausführenTestStatic.class.getMethod("staticMethod");
. Der statische Initialisierer wird nicht aufgerufen. Weitere Informationen hier docs.oracle.com/javase/specs/jvms/se10/html/…