04.03.07 Verwendung von static

Bisher haben wir ausschließlich sogenannte Objektattribute und Objektmethoden verwendet. Eine Ausnahme stellte lediglich die main Methode dar. Um aber nun Attribute und Methoden unabhängig von einem konkreten Objekt zu verwenden, gibt es die Möglichkeit des Modifizierers static.

Verwendung von static

Erinnern wir uns an unsere Klasse Bier aus dem Beispiel zu den Sichtbarkeitsmodifizierern.

Dort hatten wir die Attribute

private String name;
private double stammwuerze;

und folgende Methoden

public void setzeName(String aNeuerName) {…}
public void setzeStammwuerze(double aNeueStamwuerze) {…}
public void ausgabe() {…}

All diese Elemente hatten eines gemeinsam – man musste erst ein Objekt der Klasse Bier instanziieren (z.B. andechs) um damit arbeiten zu können.

Bier andechs = new Bier();

andechs.setzeName("Andechs Doppelbock");
andechs.setzeStammwuerze(18.5);

Der Zugriff erfolgte dann über objektName.attribut/methode.
Java bietet aber die Möglichkeit auch unabhängig von einem Objekt Attribute und Methoden einer Klasse verwenden zu können. Dazu wird bei der Deklaration eines solchen Elementes das Schlüsselwort static verwendet. Die daraus entstandenen Attribute und Methoden nennt man Klassenattribute bzw. Klassenmethoden. Sie sind unabhängig von einem Objekt und gehören zu einer speziellen Klasse.
Wir wollen dies mit einem Beispiel näher erläutern.

Nehmen wir an, wir haben Bierkästen, welche immer Platz für 20 Flaschen bieten.
Dies gilt ja dann zwangsläufig für jeden dieser Bierkästen. Somit wäre es wünschenswert, wenn wir nicht jedem Objekt Bierkasten den Wert „20“ zuweisen müssten, sondern dies global für alle solche Bierkästen gelten würde.

public class Bierkasten {
	
  private static int inhalt;
  private String bierSorte;
	
  public static void setzeInhalt(int aInhalt) {		
    Bierkasten.inhalt = aInhalt;
  }
	
  public void setzeBiersorte(String aBiersorte) {		
    this.bierSorte = aBiersorte;
  }
	
  public void ausgabe() {
		
    System.out.println("Dieser Bierkasten enthält " + Bierkasten.inhalt + " Flaschen" );
    System.out.println("der köstlichen Marke " + this.bierSorte + ".");
  }
}

Unsere Klasse Bierkasten enthält die schon gewohnte Deklaration von Objektattributen und Objektmethoden.

private String bierSorte;
public void setzeBiersorte(String aBiersorte) {…}
public void ausgabe() {…}

Neu ist die Verwendung von static bei einem Attribut und einer Methode dieser Klasse.

private static int inhalt;
public static void setzeInhalt(int aInhalt) {…}

Damit beschreiben wir ein Attribut und eine Methode, welche zu der Klasse Bierkasten gehören und nicht von der Existenz eines Objektes abhängig sind. Diese statischen Elemente gelten für alle Objekte gleichermaßen. Da es kein Objekt geben muss, um solche Klassenelemente anzusprechen, benötigt man einen entsprechenden Zugriffsmechanismus.

Der Zugriff auf solche statischen Elemente erfolgt über

KlassenName.attribut
bzw.
KlassenName.methode

Im Beispiel:

Bierkasten.inhalt = aInhalt;

Wir testen nun unsere Klasse Bierkasten in einem Testprogramm.

public class Test {
	
  public static void main(String[] args) {
	
    Bierkasten.setzeInhalt(20);
		
    Bierkasten kasten1 = new Bierkasten();
    Bierkasten kasten2 = new Bierkasten();
    kasten1.setzeBiersorte("Paulaner Schwarzbier");
    kasten2.setzeBiersorte("Sternburg Export");
    kasten1.ausgabe();
    kasten2.ausgabe();
  }
}

Hier setzen wir den Wert für den Inhalt eines Bierkastens auf „20“, ohne ein Objekt zu benutzen. Wir verwenden nur den Namen der Klasse und die zu verwendende Methode.

Bierkasten.setzeInhalt(20);

Danach erzeugen wir zwei Objekte – kasten1 und kasten2. Diesen wird eine Biersorte zugewiesen und danach der Inhalt ausgegeben.

Dieser Bierkasten enthält 20 Flaschen
der köstlichen Marke Paulaner Schwarzbier.
Dieser Bierkasten enthält 20 Flaschen
der köstlichen Marke Sternburg Export.

Sie sehen also, dass beide Objekte dasselbe Klassenattribut Bierkasten.inhalt verwenden.

Erweitern wir unsere Klasse Test etwas, um dies besser nachvollziehen zu können.

Bierkasten.setzeInhalt(20);
		
Bierkasten kasten1 = new Bierkasten();
Bierkasten kasten2 = new Bierkasten();
kasten1.setzeBiersorte("Paulaner Schwarzbier");
kasten2.setzeBiersorte("Sternburg Export");
kasten1.ausgabe();
kasten2.ausgabe();
	
Bierkasten.setzeInhalt(24);

kasten1.ausgabe();
kasten2.ausgabe();

Wir setzten den Wert des Inhaltes nach einer ersten Ausgabe auf „24“ und geben den Inhalt der Objekte kasten1 und kasten2 erneut aus, ohne an diesen Objekten etwas geändert zu haben.

Dieser Bierkasten enthält 20 Flaschen
der köstlichen Marke Paulaner Schwarzbier.
Dieser Bierkasten enthält 20 Flaschen
der köstlichen Marke Sternburg Export.
Dieser Bierkasten enthält 24 Flaschen
der köstlichen Marke Paulaner Schwarzbier.
Dieser Bierkasten enthält 24 Flaschen
der köstlichen Marke Sternburg Export.

Wichtig ist, dass man zwar von Objektmethoden aus auf statische Elemente zugreifen kann, dies anders herum aber nicht gestattet ist. In unserem Beispiel verwendet die Methode ausgabe der Klasse Bierkasten das Klassenattribut inhalt.

public void ausgabe() {
		
  System.out.println("Dieser Bierkasten enthält " + <strong>Bierkasten.inhalt</strong> + " Flaschen" );
  …
}

Dies ist möglich, da bei der ersten Verwendung der Klasse Bierkasten alle statischen Elemente initialisiert werden. Sobald also irgendwo im Quellcode der Klassenname Bierkasten auftaucht, wird diese Klasse das erste Mal initialisiert und somit auch alle Klassenattribute und -methoden.
Wollen wir aber beispielsweise von einer Klassenmethode aus auf ein Objektattribut zugreifen, erhalten wir eine Fehlermeldung.

public static void ausgabeBiersorte() {
		
  System.out.println(bierSorte);
}

Basierend auf unserem Bierkastenbeispiel führt obige Klassenmethode mit dem Zugriff auf das Objektattribut bierSorte zu folgendem Fehler.

Cannot make a static reference to the non-static field bierSorte

Hintergrund ist der, dass das Attribut bierSorte zu einem konkreten Objekt gehört und somit auch erst nach der Erzeugung eines Solchen zur Verfügung steht. Wir haben aber gerade gelernt, dass statische Elemente auch ohne konkretes Objekt existieren und somit kann man auch nicht auf etwas zugreifen was gar nicht vorhanden ist. Ebenso ist es unmöglich bei mehreren existierenden Objekten des Typs Bierkasten festzustellen, von welchem wir nun das Attribut bierSorte haben möchten.

Verwendung findet diese Art der Klassenattribute und –methoden bei Konstanten und von Objekten unabhängige Berechnungen, Ausgaben usw. Die Klasse Math ist ein gutes Beispiel hierfür, da wir kein spezielles Math-Objekt benötigen um eine Berechnung durchzuführen, sondern dies alles durch die übergebenen Parameter möglich ist.

Math.sin(45);
// oder auch Konstanten
Math.PI;

Dies war ein erster Überblick zu der Verwendung von static um von Objekten losgelöste Attribute und Methoden zu definieren. Damit ist es möglich, dass alle Objekte einer Klasse mit denselben Werten arbeiten können. Ebenso eignen sich Klassenattribute um Konstanten zu definieren. Wie man mit Hilfe von static Werte beim Laden einer Klasse initialisieren kann, erfahren Sie in Kapitel 04.03.08 Konstruktoren.

2 Replies to “04.03.07 Verwendung von static”

Schreibe einen Kommentar

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