static in Java
Willemers Informatik-Ecke
Abstrakte Klassen Java Object und Wrapper

Klassenattribute

Ein Attribut gehört normalerweise zum Objekt. Die Klasse Auto beschreibt das Attribut ps. Das heißt, jedes Auto hat seine eigene PS-Zahl. Ein R4 hat eine andere PS-Zahl als ein Maserati.
class Auto {
    int ps;
}
Der Zugriff erfolgt über ein Objekt der Klasse:
Auto r4 = new Auto();
r4.ps = 34;
Wird dem Attribut das Schlüsselwort static vorangestellt, gehört das Attribut nicht mehr zum Objekt, sondern zur Klasse. So zählt im folgenden Beispiel die Variable zulassungen, wie oft der Konstruktor aufgerufen wurde.
class Auto {
    static int zulassungen = 0;
    int ps;
    public Auto() {
        zulassungen++;
    }
}
Der Zugriff auf das Attribut zulassungen kann über ein beliebiges Objekt der Klasse Auto, aber auch über die Klasse Auto selbst erfolgen. Das nicht-statische Attribut ps muss dagegen über ein existierendes Objekt erfolgen und nicht über den Klassennamen.
Auto r4 = new Auto();
Auto a4 = new Auto();
r4.ps = 34;
System.out.println(r4.ps);  // Zugriff auf das Objekt-Attribut
System.out.println(Auto.zulassungen); // Klassen-Attribut
System.out.println(r4.zulassungen); // Auch per Objekt möglich!
System.out.println(a4.zulassungen); // dasselbe wie bei r4
System.out.println(Auto.ps); // Das knallt und gibt Compilerfehler
Ein mit static gekennzeichnet Attribut existiert genau ein Mal pro Klasse. Dabei ist die Existenz eines Objekts dieser Klasse nicht erforderlich.

Das statische Attribut kann über den Klassennamen referenziert werden.

Klassenmethoden

Auch Methoden können als static gekennzeichnet werden. Damit sind die Methoden über ihren Klassennamen aufrufbar, ohne dass es ein Objekt der Klasse geben muss.

Die Methode main

Die bekannteste Verwendung von static dürfte die für die Methode main sein.
public static void main(String[] args) {
Eine static-Methode existiert und ist aufrufbar, auch wenn noch kein Objekt erzeugt wurde. Die Methode main wird als Einsprungpunkt benötigt, bevor das erste Objekt angelegt wurde.

Pro Klasse darf es nur einen Einsprungpunkt geben. Prinzipiell kann also jede Klasse eine eigene static-Methode main haben. Das kann praktisch sein, um Tests für die Klasse zu schreiben.

Gibt es in einem Projekt mehrere Klassen mit einer Startmethode main, muss bei der Erzeugung von JAR-Dateien festgelegt werden, welche davon das Programm starten soll.

Die Klasse Math

Die Klasse Math stellt mathematische Methoden zur Verfügung. Sie braucht keine Attribute und darum auch kein Objekt, über das die Methoden aufgerufen werden.
minimum = Math.min(a, b);

Klassenkostanten

Konstanten (also Variablen mit dem Modifizierer final werden typischerweise als Klassenvariablen deklariert, also auch mit dem Schlüsselwort static versehen.

class Spiel {
    public static final int MINEN = 12;
Der Zugriff kann so direkt über den Klassennamen erfolgen:
private Minen[] minen = new Minen[Spiel.MINEN];

Klassenkonstruktor

Es gibt auch einen Klassenkonstruktor, der allerdings selten Anwendung findet.
class MeineKlasse {
   static {
        // ...
   }
   // ...
}
Ein static-Element wird üblicherweise über den Klassennamen aufgerufen. Da Klassennamen mit einem Großbuchstaben beginnen und Objekte mit Kleinbuchstaben, kann am Aufruf erkannt werden, ob das Element static ist, sofern man sich an diese Konventionen hält.

static erzwingt static

Da ein static-Element bereits existieren kann, bevor das erste Objekt der Klasse angelegt wird, kann es nicht auf normale Attribute zugreifen oder normale Methoden aufrufen. Dagegen können Objektmethoden neben den normalen Attributen und Methoden sowohl Klassenmethoden als auch Klassenattribute verwenden.

Damit eine Klasse mit der Methode main nicht nur statische Elemente verwendet, kann man sich leicht helfen, einen new auf die eigene Klasse aufzurufen und damit ein Objekt zu erzeugen. Die weitere Programmierung kann dann im Konstruktor erfolgen. Dieses Vorgehen wird gern in Swing-JFrame-Klassen verfolgt.

public class MeinJFrame extends JFrame {
    public MeinJFrame() {
        this.setSize(400, 300);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new MeinJFrame();
    }
}

Singleton

Objekte, die nur einmal auftauchen, können natürlich über static-Attribute und -Methoden in einer Klasse definiert werden. Diese Vorgehensweise ist allerdings unüblich und führt zu unübersichtlichen Programmen. Gebräuchlicher ist die Verwendung eines Singletons, der seinerseits aber static-Mechanismen verwendet.

Ein Singleton ist ein Klasse, von der es höchstens ein Objekt geben kann.

class Singleton {
    private Singleton() { }
    private static Singleton instance = null;
    static public  Singleton getInstance() {
        if (instance==null) {
            instance = new Singleton();
        }
        return instance;
    }
}
Die Singleton-Klasse kann durch beliebige nicht-statische Attribute und Methoden ergänzt werden. Diese müssen nicht statisch sein, da sie über das durch getInstance ermittelte Objekt aufgerufen werden. Der erste Aufruf von getInstance erzeugt die Instanz.

Das Objekt wird nur angelegt, wenn es wirklich gebraucht wird und zwar bei seiner ersten Verwendung. Da es nur ein Objekt gibt, muss es im Programm nicht gespeichert werden, sondern kann per getInstance jederzeit beschafft werden.

Das Zulassungsbeispiel als Singleton ist natürlich etwas üppiger als die Verwendung einer einzigen statischen Variablen:

class Zulassung {
    private Zulassung() { }
    private static Zulassung instance = null;
    static public  Zulassung getInstance() {
        if (instance==null) {
            instance = new Zulassung();
        }
        return instance;
    }
    private int zulassungen = 0;
    public void zulassen() {
        zulassungen++;
    }
}
Das Auto lässt sich zu:
class Auto {
    int ps;
    public Auto() {
        Zulassung zulassung = Zulassung.getInstance()
        zulassung.zulassen();
    }
}
oder kürzer:
class Auto {
    int ps;
    public Auto() {
        Zulassung.getInstance().zulassen();
    }
}

Videos

Thema static

Thema Singleton


Abstrakte Klassen Java Object und Wrapper