Eine Anleitung zum statischen Schlüsselwort in Java

1. Einleitung

In diesem Artikel werden wir das statische Schlüsselwort der Java-Sprache im Detail untersuchen. Wir werden herausfinden, wie wir statische Schlüsselwörter auf Variablen, Methoden, Blöcke, verschachtelte Klassen anwenden können und welchen Unterschied dies macht.

2. Die Anatomie des statischen Schlüsselworts

In der Programmiersprache Java gibt das Schlüsselwort static an, dass das bestimmte Mitglied zu einem Typ selbst und nicht zu einer Instanz dieses Typs gehört .

Dies bedeutet, dass nur eine Instanz dieses statischen Elements erstellt wird, die von allen Instanzen der Klasse gemeinsam genutzt wird.

Das Schlüsselwort kann auf Variablen, Methoden, Blöcke und verschachtelte Klassen angewendet werden.

3. Die statischen Felder (oder Klassenvariablen)

Wenn in Java ein Feld als statisch deklariert wird , wird genau eine einzelne Kopie dieses Felds erstellt und von allen Instanzen dieser Klasse gemeinsam genutzt . Es spielt keine Rolle, wie oft wir eine Klasse initialisieren. Es wird immer nur eine Kopie des dazugehörigen statischen Feldes geben. Der Wert dieses statischen Felds wird für alle Objekte derselben Klasse geteilt.

Aus Speichersicht befinden sich statische Variablen in einem bestimmten Pool im JVM-Speicher namens Metaspace (vor Java 8 wurde dieser Pool Permanent Generation oder PermGen genannt, der vollständig entfernt und durch Metaspace ersetzt wurde).

3.1. Beispiel für das statische Feld

Angenommen, wir haben eine Car- Klasse mit mehreren Attributen (Instanzvariablen) . Immer wenn neue Objekte aus dieser Auto- Blaupause initialisiert werden , hat jedes neue Objekt eine eigene Kopie dieser Instanzvariablen.

Allerdings nehmen wir für eine Variable suchen, der die Zählung der Anzahl von hält Auto Objekte , die initialisiert werden und wird in allen Fällen so geteilt , dass sie darauf zugreifen können und es auf ihre Initialisierung erhöhen.

Hier kommen statische Variablen ins Spiel:

public class Car { private String name; private String engine; public static int numberOfCars; public Car(String name, String engine) { this.name = name; this.engine = engine; numberOfCars++; } // getters and setters }

Jetzt wird für jedes Objekt dieser Klasse, das initialisiert wird, dieselbe Kopie der Variablen numberOfCars inkrementiert. Für diesen Fall gelten also die folgenden Aussagen:

@Test public void whenNumberOfCarObjectsInitialized_thenStaticCounterIncreases() { new Car("Jaguar", "V8"); new Car("Bugatti", "W16"); assertEquals(2, Car.numberOfCars); }

3.2. Überzeugende Gründe für die Verwendung statischer Felder

  • Wenn der Wert der Variablen unabhängig von Objekten ist
  • Wenn der Wert für alle Objekte freigegeben werden soll

3.3. Wichtige Punkte, an die Sie sich erinnern sollten

  • Da statische Variablen zu einer Klasse gehören, kann direkt über den Klassennamen auf sie zugegriffen werden und benötigt keine Objektreferenz
  • statische Variablen können nur auf Klassenebene deklariert werden
  • Auf statische Felder kann ohne Objektinitialisierung zugegriffen werden
  • Obwohl wir über eine Objektreferenz (wie ford.numberOfCars ++ ) auf statische Felder zugreifen können , sollten wir darauf verzichten, da es in diesem Fall schwierig wird, herauszufinden, ob es sich um eine Instanzvariable oder eine Klassenvariable handelt. Stattdessen sollten wir immer auf statische Variablen mit dem Klassennamen verweisen (in diesem Fall beispielsweise Car.numberOfCars ++ ).

4. Die statischen Methoden (oder Klassenmethoden)

Ähnlich wie statische Felder gehören auch statische Methoden zu einer Klasse anstelle des Objekts. Sie können daher aufgerufen werden, ohne das Objekt der Klasse zu erstellen, in der sie sich befinden. Sie sollen verwendet werden, ohne Objekte der Klasse zu erstellen.

4.1. Beispiel einer statischen Methode

Statische Methoden werden im Allgemeinen verwendet, um eine Operation auszuführen, die nicht von der Instanzerstellung abhängig ist.

Wenn es einen Code gibt, der für alle Instanzen dieser Klasse freigegeben werden soll, schreiben Sie diesen Code in einer statischen Methode:

public static void setNumberOfCars(int numberOfCars) { Car.numberOfCars = numberOfCars; }

Statische Methoden werden auch häufig zum Erstellen von Dienstprogramm- oder Hilfsklassen verwendet, damit sie abgerufen werden können, ohne ein neues Objekt dieser Klassen zu erstellen.

Schauen Sie sich einfach die Collections- oder Math-Dienstprogrammklassen von JDK, StringUtils von Apache oder CollectionUtils von Spring Framework an und stellen Sie fest, dass alle Methoden statisch sind .

4.2. Überzeugende Gründe für die Verwendung statischer Methoden

  • Zugriff auf / Bearbeitung von statischen Variablen und anderen statischen Methoden, die nicht von Objekten abhängen
  • statische Methoden werden häufig in Dienstprogramm- und Hilfsklassen verwendet

4.3. Wichtige Punkte, an die Sie sich erinnern sollten

  • statische Methoden in Java werden zur Kompilierungszeit aufgelöst. Da das Überschreiben von Methoden Teil des Laufzeitpolymorphismus ist, können statische Methoden nicht überschrieben werden
  • abstrakte Methoden können nicht statisch sein
  • statische Methoden können dieses oder Super- Schlüsselwörter nicht verwenden
  • Die folgenden Kombinationen von Instanz, Klassenmethoden und Variablen sind gültig:
    1. Instanzmethoden können direkt auf Instanzmethoden und Instanzvariablen zugreifen
    2. Instanzmethoden können auch direkt auf statische Variablen und statische Methoden zugreifen
    3. statische Methoden können auf alle statischen Variablen und andere statische Methoden zugreifen
    4. statische Methoden können nicht direkt auf Instanzvariablen und Instanzmethoden zugreifen . Dazu benötigen sie eine Objektreferenz

5. Ein statischer Block

Ein statischer Block wird zum Initialisieren statischer Variablen verwendet. Obwohl statische Variablen direkt während der Deklaration initialisiert werden können, gibt es Situationen, in denen wir die mehrzeilige Verarbeitung durchführen müssen.

In solchen Fällen sind statische Blöcke nützlich.

Wenn statische Variablen während der Initialisierung zusätzliche Logik mit mehreren Anweisungen erfordern, kann ein statischer Block verwendet werden.

5.1. Das statische Blockbeispiel

Angenommen, wir möchten ein Listenobjekt mit einigen vordefinierten Werten initialisieren.

Dies wird mit statischen Blöcken einfach :

public class StaticBlockDemo { public static List ranks = new LinkedList(); static { ranks.add("Lieutenant"); ranks.add("Captain"); ranks.add("Major"); } static { ranks.add("Colonel"); ranks.add("General"); } }

In diesem Beispiel wäre es nicht möglich, das List- Objekt mit allen Anfangswerten zusammen mit der Deklaration zu initialisieren . und deshalb haben wir hier den statischen Block verwendet.

5.2. Überzeugende Gründe für die Verwendung statischer Blöcke

  • Wenn die Initialisierung statischer Variablen eine zusätzliche Logik außer der Zuweisung erfordert
  • Wenn die Initialisierung statischer Variablen fehleranfällig ist und eine Ausnahmebehandlung erfordert

5.3. Wichtige Punkte, an die Sie sich erinnern sollten

  • Eine Klasse kann mehrere statische Blöcke haben
  • statische Felder und statische Blöcke werden in derselben Reihenfolge aufgelöst und ausgeführt, in der sie in der Klasse vorhanden sind

6. Eine statische Klasse

Mit der Programmiersprache Java können wir eine Klasse innerhalb einer Klasse erstellen. Es bietet eine überzeugende Möglichkeit, Elemente zu gruppieren, die nur an einem Ort verwendet werden sollen. Dies trägt dazu bei, unseren Code besser organisiert und lesbar zu halten.

Die verschachtelte Klassenarchitektur ist in zwei Bereiche unterteilt:

  • Verschachtelte Klassen, die als statisch deklariert sind, werden als statisch verschachtelte Klassen bezeichnet .
  • nested classes that are non-static are called inner classes

The main difference between these two is that the inner classes have access to all member of the enclosing class (including private), whereas the static nested classes only have access to static members of the outer class.

In fact, static nested classes behaved exactly like any other top-level class but enclosed in the only class which will access it, to provide better packaging convenience.

6.1. Example of static Class

The most widely used approach to create singleton objects is through static nested class is it doesn't require any synchronization and is easy to learn and implement:

public class Singleton { private Singleton() {} private static class SingletonHolder { public static final Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } }

6.2. Compelling Reasons to Use a static Inner Class

  • Grouping classes that will be used only in one place increases encapsulation
  • The code is brought closer to the place that will be only one to use it; this increases readability and code is more maintainable
  • If nested class doesn't require any access to it's enclosing class instance members, then it's better to declare it as static because this way, it won't be coupled to the outer class and hence will be more optimal as they won't require any heap or stack memory

6.3. Key Points to Remember

  • static nested classes do not have access to any instance members of the enclosing outer class; it can only access them through an object's reference
  • statisch verschachtelte Klassen können auf alle statischen Mitglieder der einschließenden Klasse zugreifen, einschließlich privater
  • Die Java-Programmierspezifikation erlaubt es uns nicht, die Klasse der obersten Ebene als statisch zu deklarieren . Nur Klassen innerhalb der Klassen (verschachtelte Klassen) können als statisch festgelegt werden

7. Fazit

In diesem Artikel haben wir das statische Schlüsselwort in Aktion gesehen. Wir lesen auch die Gründe und Vorteile für die Verwendung statischer Felder, statischer Methoden, statischer Blöcke und statischer innerer Klassen.

Wie immer finden wir den vollständigen Code auf GitHub.