04.03.09 Statische Initialisierer

Sie wissen nun bereits wie wichtig es ist Objektzustände bereits zur Initialisierung mit sinnvollen Werten zu versehen. Dies geschah mit Hilfe der sogenannten Konstruktoren.
Was aber wenn eine Klasse, neben den im Konstruktor zu initialisierenden Objekteigenschaften, zusätzlich noch weitere Klasseneigenschaften besitzt?

Statische Initialisierer

Im Kapitel 04.03.07 Verwendung von static wurde beschrieben, wie Attribute und Methoden losgelöst von einer konkreten Instanz einer Klasse definiert werden können. Diese wurden Klassenattribute bzw. Klassenmethoden genannt. Für Objektattribute haben wir die Möglichkeit der verschiedenen Konstruktoren kennen gelernt, um diese Eigenschaften bereits bei der Erzeugung mit sinnvollen Werten zu versehen.
Statische Initialisierer helfen uns komplexe Klassenattribute bereits beim Laden der Klasse zu initialisieren.

Wie Sie schon wissen, erfolgt die Deklaration einfacher Klassenattribute folgendermaßen.

public class MeineKlasse {
	
  public static int meinX = 0;
  public static final String VERSION = "JBB 1.0";
}

Der Modifizierer final sorgt dafür, dass das Objekt nicht verändert werden kann. Mehr hierzu erfahren Sie im Kapitel über weitere Modifizierer

Bei einfach zu initialisierenden Klassenattributen erfolgt die Initialisierung bereits bei der Deklaration (siehe Beispiel oben). Dies sollte auch immer der bevorzugte Weg sein.
Bei komplexen Klassenattributen verwenden wir einen static Block um diese zu initialisieren.

public class MeineKlasse {
	
  static { /* Initialisierung */ }
}

Innerhalb der Klasse schreiben wir static gefolgt von einem geschweiften Klammerpaar. Dies ist dann unser Statischer Initialisierer. Man kann auch mehrere solcher Blöcke innerhalb der Klasse schreiben. Diese werden aber trotzdem ihrer Reihenfolge im Quellcode entsprechend in einem Zug abgearbeitet. Um die Übersichtlichkeit zu wahren, sollte man sich aber auf einen solchen Block beschränken.

public class ZufallsZahlen {
	
  private static final int MAX = 20;
  private static int[] zufallszahlen;
	
  static {
		
    ZufallsZahlen.zufallszahlen = new int[ZufallsZahlen.MAX];
		
    Random rand = new Random(System.currentTimeMillis());
		
    for(int i = 0; i < ZufallsZahlen.MAX; i++) {
			
      ZufallsZahlen.zufallszahlen&#91;i&#93; = rand.nextInt(50);
    }
  }
	
  public static void ausgabe() {
		
    for(int i = 0; i < ZufallsZahlen.MAX; i++) {
			
      System.out.println(ZufallsZahlen.zufallszahlen&#91;i&#93;);;
    }
  }
	
  public static void main(String&#91;&#93; args) {
    ZufallsZahlen.ausgabe();
  }
}&#91;/sourcecode&#93;

In unserer Klasse <code>ZufallsZahlen</code> deklarieren wir die zwei Klassenattribute <code>MAX</code> und <code>zufallszahlen</code>. Das Attribut <code>MAX</code> wird gleich mit "20" initialisiert, wohingegen die Initialisierung des Attributes <code>zufallszahlen</code> zu komplex wird, um es direkt bei der Deklaration zu erledigen. Aus diesem Grund verwenden wir einen statischen Initialisierer. Hier wird ein neues <code>int</code> Array angelegt und mit Zufallszahlen gefüllt. In unserer <code>main</code> Methode rufen wir lediglich die Methode <code>ausgabe</code> auf, um uns die Zahlen anzeigen zu lassen. Die komplette Initialisierung des Arrays wurde bereits direkt beim Laden der Klasse <code>ZufallsZahlen</code> durchgeführt. Somit steht also dem direkten Aufruf von <code>ausgabe</code> in der <code>main</code> Methode nichts im Wege.

<strong>Fazit</strong>

Um komplexe Klassenattribute zu initialisieren, bietet sich ein Statischer Initialisierer an. Dieser wird direkt beim Laden der Klasse abgearbeitet. Von einem solchen Initialisierer hat man keinen Zugriff auf Objektattribute bzw. Objektmethoden – analog zu anderen Klassenmethoden.  Die verwendeten Klassenattribute müssen schon vor dem statischen Initialisierer deklariert werden, um bekannt zu sein. Sollten als <code>final</code> markierte Klassenattribute nicht direkt bei der Deklaration initialisiert werden, so <strong>muss</strong> dies zwingend in einem solchen static Block geschehen.

<strong>Ausblick</strong>

Analog zu den statischen Initialisierern existieren noch Instanz Initialisierer. Diese entsprechen den parameterlosen Konstruktoren und finden dementsprechend (fast) nur Verwendung bei der Initialisierung von anonymen Klassen, da hier kein Klassenname zur Benennung des Konstruktors zu Verfügung steht.

Mit Hilfe der soeben kennen gelernten statischen Initialisierer kann man auch Programme schreiben, welche komplett ohne die allgegenwärtige <code>main</code> Methode auskommen.

public class OhneMain {
	
  static {
		
    System.out.println("Hallo Welt!");
    System.exit(0);
  }
}

Man muss dabei jedoch darauf achten, dass die Anwendung nach Abarbeitung des statischen Blockes mit System.exit beendet wird. Ist dies nicht der Fall, versucht die Virtual Machine eine nicht vorhandene main Methode zu starten. Wir erhalten eine Fehlermeldung:

Hallo Welt!
java.lang.NoSuchMethodError: main
Exception in thread "main"

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.