Initialisierer in Java
Exemplarinitialisierer
Die direkte Initialisierung eines Feldes erfolgt vor der Ausführung des Konstruktors (JLS3, 12.5).
Main.java
public final class Main
{ int a(){ java.lang.System.out.println( "a" ); return 97; }
int d(){ java.lang.System.out.println( "d" ); return 100; }
int number = a();
Main(){ number = d(); }
public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( new Main().number ); }}transcript
a
d
100
Ein Block direkt im Rumpf einer Klasse wird Initialisierer genannt.
Main.java
public final class Main
{ { number = b(); }
int a(){ java.lang.System.out.println( "a" ); return 97; }
int b(){ java.lang.System.out.println( "b" ); return 98; }
int c(){ java.lang.System.out.println( "c" ); return 99; }
int d(){ java.lang.System.out.println( "d" ); return 100; }
int number = a();
Main(){ number = d(); }
public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( new Main().number ); }
{ number = c(); }}transcript
b
a
c
d
100
Typischer Anfängerfehler:
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( "alpha" ); }
{ java.lang.System.out.println( "beta" ); }}transcript
alpha
Warum erscheint »beta« nicht?
Die Reihenfolge der Schritte bei der Initialisierung
eines Objekts:Vereinfacht:
0 Felder werden auf Vorgabewerte der Sprache gesetzt
1 Der Konstruktur wird aktiviert.
Dazu gehören die Schritte:1.0 Der (implizite oder im Konstruktorrumpf
aufgerufene) Konstruktor der Oberklasse
wird aktiviert.1.1 Die expliziten Initialisierungen von
Variablen und des Exemplars werden in der
Reihenfolge ausgeführt, wie sie im Quelltext
der Klasse des Exemplars stehen.1.2 Der Rest des Konstruktorrumpfs wird ausgeführt.
Beispiel:class B
{ int a = Do.print( "B0" );
{ Do.print( "B1" ); }
int b = Do.print( "B2" );
public B(){ Do.print( "b" ); }
{ Do.print( "B3" ); }}class A extends B
{ int c = Do.print( "A0" );
{ Do.print( "A1" ); }
int d = Do.print( "A2" );
public A(){ Do.print( "a" ); }
{ Do.print( "A3" ); }}public final class Main
{ public static void main( final java.lang.String[] args )
{ new A(); }}class Do
{ public static int print( final java.lang.String text )
{ java.lang.System.err.println( text ); return 1; }}
/* Ausgabe
B0
B1
B2
B3
b
A0
A1
A2
A3
a
*/
Exemplarinitialisierer in anonymer innerer Klasse
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ final java.util.List< java.lang.Integer >list =
new java.util.ArrayList< java.lang.Integer >()
{ { add( 2 ); add( 4 ); add( 7 ); }};
java.lang.System.out.println( list ); }}transcript
[2, 4, 7]
Statische Initialisierer
Ein Block direkt im Rumpf einer Klasse wird statischer Initialisierer genannt, wenn er mit dem Schlüsselwort »static« gekennzeichnet ist.
Er wird nach dem Laden der Klasse ausgeführt.
Main.java
public final class Main
{ static { java.lang.System.out.print( "hello, " ); }
public static void main( final java.lang.String[] args ){ java.lang.System.out.println(); }
static { java.lang.System.out.print( "world!" ); }}transcript
hello, world!
Main.java
final class C
{ C(){ java.lang.System.out.print( "hello, " ); }}public final class Main
{ static C c = new C();static { java.lang.System.out.println( "world" ); }
public static void main( final java.lang.String[] args )
{ }}transcript
hello, world