Kategorien
Allgemein

Immer eins nach dem anderen

Ein kleines Beispiel zeigt, wo die Reihenfolge der Deklaration von Variablen in Java Klassen wichtig ist.

Auf der Tomcat Mailingliste kam heute eine Mail, in der jemand fragte, warum sein Singleton im Tomcat nicht einamlig in der JVM vorhanden war. Die Lösung war wohl, dass er zwei verschiedene Classloader benutzte und daher zwei verschiedene Instanzen.

Ein anderes Problem seines Codes war aber ganz anderer Natur. Der Code sah etwa so aus:

public class Singleton {
    private static Singleton instance = new Singleton();
    private static int counter = 0;

    private Singleton() {
         System.out.println("Counter: " + (++counter));
    }

    public static getInstance() {
        return instance;
    }

    public int getCounter() {
        return counter;
    }
}

Auf den ersten Blick sieht das in Ordnung aus. Der Konstruktor gibt brav ein "Counter: 1" aus und man ahnt nichts böses. Bis dann ein kleiner Testfall mit jUnit aufkreuzt:

public class SingletonTest extends TestCase {
     public void testSingletonCounter() {
          Singleton instance = Singleton.getInstance();
          assertEquals(instance.getCounter(), 1,
              "Es kann nur einen geben");
     }
}

Hier wird dann plötzlich klar, dass intern der counter trotz anderweitiger Ausgabe wieder auf 0 gesetzt wurde. Das liegt daran, dass die Initialisierung der statischen Klassenvariablen der Reihe nach geschieht. Im Konstruktor ist counter also erstmal nicht definiert – implizit also null – und wird dann auf eins inkrementiert. Nach dem Konstruktor wird dann die vermeintlich noch nicht initialsierte Variable auf 0 gesetzt.

Das kann ganz schön ins Auge gehen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.