Java-Modifikatoren

Die Java-Sprache bietet viele Modifikatoren, die hauptsächlich in die folgenden zwei Kategorien unterteilt werden:

  • Zugriffsmodifikatoren
  • Nicht-Zugriffsmodifikatoren

Modifikatoren werden verwendet, um Klassen, Methoden oder Variablen zu definieren, und stehen normalerweise ganz am Anfang einer Anweisung. Wir veranschaulichen dies mit dem folgenden Beispiel:

public class ClassName { // ... } private boolean myFlag; static final double weeks = 9.5; protected static final int BOXWIDTH = 42; public static void main(String[] arguments) { //Methodenkörper }

Zugriffssteuerungsmodifikatoren

In Java können Zugriffssteuerungsmodifizierer verwendet werden, um den Zugriff auf Klassen, Variablen, Methoden und Konstruktoren zu schützen. Java unterstützt 4 verschiedene Zugriffsebenen.

  • default(d. h. Standard, nichts geschrieben): Sichtbar innerhalb desselben Pakets, ohne einen Modifizierer zu verwenden. Gilt für: Klassen, Schnittstellen, Variablen, Methoden.

  • private: Sichtbar innerhalb derselben Klasse. Gilt für: Variablen, Methoden.Hinweis: Kann Klassen (äußere Klassen) nicht ändern

  • public: Für alle Klassen sichtbar. Gilt für: Klassen, Schnittstellen, Variablen, Methoden

  • protected: Sichtbar für Klassen im selben Paket und alle Unterklassen. Gilt für: Variablen, Methoden.Hinweis: Kann Klassen (äußere Klassen) nicht ändern。

Wir können die Zugriffsebenen mit der folgenden Tabelle veranschaulichen:

Zugriffskontrolle
Modifizierer Aktuelle Klasse Gleiches Paket Unterklassen (gleiches Paket) Unterklassen (anderes Paket) Andere Pakete
public Y Y Y Y Y
protected Y Y Y Y/N(Beschreibung) N
default Y Y Y N N
private Y N N N N

Standard-Zugriffsmodifizierer – Ohne Verwendung eines Schlüsselworts

Wenn in der Definition einer Klasse, Variablen, Methode oder eines Konstruktors kein Zugriffsmodifizierer angegeben ist, haben sie standardmäßig den Standard-Zugriffsmodifizierer.

Die Zugriffsebene des Standard-Zugriffsmodifizierers ist Paketebene, was bedeutet, dass nur andere Klassen im selben Paket darauf zugreifen können.

Wie im folgenden Beispiel gezeigt, können Variablen und Methoden ohne Verwendung eines Modifizierers deklariert werden.

Beispiel

// MyClass.java class MyClass { //Standard-Zugriffsmodifizierer int x = 10; //Standard-Zugriffsmodifizierer void display() { //Standard-Zugriffsmodifizierer System.out.println("Wert von x ist: " + x); } } // MyOtherClass.java class MyOtherClass { public static void main(String[] args) { MyClass obj = new MyClass(); obj.display(); //Zugriff auf die Variablen und Methoden mit Standard-Zugriffsmodifizierer in MyClass } }

Im obigen Beispiel werden die Klasse MyClass und ihre Mitgliedsvariable x und Methode display() alle mit dem Standard-Zugriffsmodifizierer definiert. Die Klasse MyOtherClass befindet sich im selben Paket, sodass sie auf die Klasse MyClass und ihre Mitgliedsvariablen und -methoden zugreifen kann.

Privater Zugriffsmodifizierer - private

Der private Zugriffsmodifizierer ist die restriktivste Zugriffsebene, daher kann nur die besitzende Klasse auf alsprivatedeklarierte Methoden, Variablen und Konstruktoren zugreifen, und Klassen und Schnittstellen können nicht als deklariert werdenprivate。

Auf Variablen, die als privater Zugriffstyp deklariert sind, kann von externen Klassen nur über öffentliche Getter-Methoden in der Klasse zugegriffen werden.

Die Verwendung des privaten Zugriffsmodifizierers dient hauptsächlich dazu, die Implementierungsdetails der Klasse zu verbergen und die Daten der Klasse zu schützen.

Die folgende Klasse verwendet den privaten Zugriffsmodifizierer:

public class Logger { private String format; public String getFormat() { return this.format; } public void setFormat(String format) { this.format = format; } }

Im Beispiel ist die format-Variable in der Logger-Klasse eine private Variable, daher können andere Klassen den Wert der Variable nicht direkt abrufen oder festlegen. Um anderen Klassen zu ermöglichen, die Variable zu manipulieren, werden zwei öffentliche Methoden definiert: getFormat() (gibt den Wert von format zurück) und setFormat(String) (legt den Wert von format fest)

Öffentlicher Zugriffsmodifizierer - public

Auf Klassen, Methoden, Konstruktoren und Schnittstellen, die als public deklariert sind, kann von jeder anderen Klasse zugegriffen werden.

Wenn mehrere public-Klassen, die aufeinander zugreifen, auf verschiedene Pakete verteilt sind, müssen Sie das Paket importieren, das die entsprechenden public-Klassen enthält. Aufgrund der Vererbung von Klassen können alle public-Methoden und -Variablen einer Klasse von ihren Unterklassen geerbt werden.

Die folgende Funktion verwendet die public-Zugriffskontrolle:

public static void main(String[] Argumente) { // ... }

Die main()-Methode eines Java-Programms muss auf public gesetzt werden, andernfalls kann der Java-Interpreter die Klasse nicht ausführen.

Geschützter Zugriffsmodifizierer - protected

protected muss anhand der folgenden zwei Punkte analysiert und erklärt werden:

  • Unterklasse und Basisklasse befinden sich im selben Paket:: Auf als protected deklarierte Variablen, Methoden und Konstruktoren kann von jeder anderen Klasse im selben Paket zugegriffen werden;

  • Unterklasse und Basisklasse befinden sich nicht im selben Paket:: Dann kann in der Unterklasse eine Instanz der Unterklasse auf die von der Basisklasse geerbten protected-Methoden zugreifen, aber nicht auf die protected-Methoden einer Instanz der Basisklasse.

protected kann Datenmember, Konstruktoren und Methodenmember modifizieren.Klassen können nicht modifiziert werden (außer inneren Klassen)。

Schnittstellen und ihre Membervariablen und -methoden können nicht als protected deklariert werden. Die folgende Abbildung veranschaulicht dies:

Unterklassen können auf Methoden und Variablen zugreifen, die mit dem protected-Modifizierer deklariert wurden, wodurch verhindert wird, dass nicht verwandte Klassen diese Methoden und Variablen verwenden.

Die folgende Oberklasse verwendet den protected-Zugriffsmodifizierer, und die Unterklasse überschreibt die openSpeaker()-Methode der Oberklasse.

class AudioPlayer { protected boolean openSpeaker(Speaker sp) { //Implementierungsdetails } } class StreamingAudioPlayer extends AudioPlayer { protected boolean openSpeaker(Speaker sp) { //Implementierungsdetails } }

Wenn die openSpeaker()-Methode als private deklariert wird, kann außer AudioPlayer keine Klasse auf die Methode zugreifen.

Wenn openSpeaker() als public deklariert wird, können alle Klassen auf die Methode zugreifen.

Wenn wir die Methode nur für Unterklassen ihrer Klasse sichtbar machen wollen, dann deklarieren wir die Methode als protected.

protected ist einer der am schwierigsten zu verstehenden Zugriffsmodifizierer für Java-Klassenmitglieder. Weitere Details finden Sie unterDetaillierte Erklärung des Java-Schlüsselworts protected。

Zugriffskontrolle und Vererbung

Bitte beachten Sie die folgenden Regeln für die Methodenvererbung:

  • Methoden, die in der Oberklasse als public deklariert sind, müssen in der Unterklasse ebenfalls public sein.

  • In der Elternklasse als protected deklarierte Methoden müssen in der Unterklasse entweder als protected oder public deklariert werden und dürfen nicht als private deklariert werden.

  • In der Elternklasse als private deklarierte Methoden können nicht von der Unterklasse geerbt werden.


Nicht-Zugriffsmodifikatoren

Um einige andere Funktionen zu implementieren, bietet Java auch viele Nicht-Zugriffsmodifikatoren.

Der static-Modifikator wird verwendet, um Klassenmethoden und Klassenvariablen zu modifizieren.

final-Modifikator, wird zum Modifizieren von Klassen, Methoden und Variablen verwendet. Mit final modifizierte Klassen können nicht geerbt werden, mit final modifizierte Methoden können nicht von erbenden Klassen neu definiert werden, und mit final modifizierte Variablen sind Konstanten und können nicht geändert werden.

abstract-Modifikator, wird zum Erstellen abstrakter Klassen und abstrakter Methoden verwendet.

synchronized- und volatile-Modifikatoren, hauptsächlich in der Thread-Programmierung verwendet.

static-Modifikator

  • Statische Variablen:

    Das Schlüsselwort static wird verwendet, um statische Variablen zu deklarieren, die unabhängig von Objekten sind. Unabhängig davon, wie viele Objekte eine Klasse instanziiert, existiert ihre statische Variable nur einmal. Statische Variablen werden auch Klassenvariablen genannt. Lokale Variablen können nicht als statische Variablen deklariert werden.

  • Statische Methoden:

    Das Schlüsselwort static wird verwendet, um statische Methoden zu deklarieren, die unabhängig von Objekten sind. Statische Methoden können keine nicht-statischen Variablen der Klasse verwenden. Statische Methoden beziehen Daten aus der Parameterliste und berechnen dann die Daten.

Der Zugriff auf Klassenvariablen und -methoden kann direkt überclassname.variablenameundclassname.methodnamedie Zugriffsmethode erfolgen.

Wie im folgenden Beispiel gezeigt, wird der Modifikator static verwendet, um Klassenmethoden und Klassenvariablen zu erstellen.

public class InstanceCounter { private static int numInstances = 0; protected static int getCount() { return numInstances; } private static void addInstance() { numInstances++; } InstanceCounter() { InstanceCounter.addInstance(); } public static void main(String[] arguments) { System.out.println("Beginnend mit " + InstanceCounter.getCount() + " Instanzen"); for (int i = 0; i < 500; ++i){ new InstanceCounter(); } System.out.println("Erstellt " + InstanceCounter.getCount() + " Instanzen"); } }

Die Ausgabe beim Ausführen des obigen Beispiels ist wie folgt:

Starting with 0 instances
Created 500 instances

final-Modifizierer

final-Variablen:

final bedeutet "letzte" oder "endgültig". Sobald einer Variablen ein Wert zugewiesen wurde, kann sie nicht neu zugewiesen werden. Instanzvariablen, die durch final modifiziert werden, müssen explizit einen Anfangswert angeben.

Der final-Modifizierer wird normalerweise zusammen mit dem static-Modifizierer verwendet, um Klassenkonstanten zu erstellen.

Beispiel

public class Test{ final int value = 10; //Das Folgende ist ein Beispiel für das Deklarieren von Konstanten. public static final int BOXWIDTH = 6; static final String TITLE = "Manager"; public void changeValue(){ value = 12; //gibt einen Fehler aus } }

finale Methoden

Finale Methoden in einer Elternklasse können von Unterklassen geerbt werden, aber nicht von Unterklassen überschrieben werden.

Der Hauptzweck der Deklaration einer finalen Methode besteht darin, zu verhindern, dass der Inhalt der Methode geändert wird.

Wie unten gezeigt, deklarieren Sie eine Methode mit dem final-Modifizierer.

public class Test{ public final void changeName(){ //Methodenrumpf } }

finale Klasse

Eine finale Klasse kann nicht geerbt werden, und keine Klasse kann irgendwelche Eigenschaften einer finalen Klasse erben.

Beispiel

public final class Test { //Klassenrumpf }

abstract-Modifizierer

Abstrakte Klasse:

Eine abstrakte Klasse kann nicht zum Instanziieren von Objekten verwendet werden; der einzige Zweck der Deklaration einer abstrakten Klasse besteht darin, die Klasse in Zukunft zu erweitern.

Eine Klasse kann nicht gleichzeitig durch abstract und final modifiziert werden. Wenn eine Klasse abstrakte Methoden enthält, muss die Klasse als abstrakte Klasse deklariert werden, andernfalls tritt ein Kompilierungsfehler auf.

Eine abstrakte Klasse kann sowohl abstrakte als auch nicht abstrakte Methoden enthalten.

Beispiel

abstract class Caravan{ private double price; private String model; private String year; public abstract void goFast(); //Abstrakte Methode public abstract void changeColor(); }

Abstrakte Methode

Eine abstrakte Methode ist eine Methode ohne jegliche Implementierung; die konkrete Implementierung wird von Unterklassen bereitgestellt.

Abstrakte Methoden können nicht als final oder static deklariert werden.

Jede Unterklasse, die von einer abstrakten Klasse erbt, muss alle abstrakten Methoden der Elternklasse implementieren, es sei denn, die Unterklasse ist ebenfalls eine abstrakte Klasse.

Wenn eine Klasse mehrere abstrakte Methoden enthält, muss die Klasse als abstrakte Klasse deklariert werden. Eine abstrakte Klasse muss keine abstrakten Methoden enthalten.

Eine abstrakte Methodendeklaration endet mit einem Semikolon, zum Beispiel:public abstract sample();。

Beispiel

public abstract class SuperClass{ abstract void m(); //Abstrakte Methode } class SubClass extends SuperClass{ //Implementierung abstrakter Methoden void m(){ ......... } }

synchronized-Modifizierer

Auf eine mit dem Schlüsselwort synchronized deklarierte Methode kann jeweils nur ein Thread zugreifen. Der synchronized-Modifizierer kann auf die vier Zugriffsmodifizierer angewendet werden.

Beispiel

public synchronized void showDetails(){ ....... }

transient-Modifizierer

Wenn ein serialisiertes Objekt Instanzvariablen enthält, die mit transient modifiziert wurden, überspringt die Java Virtual Machine (JVM) diese bestimmte Variable.

Dieser Modifizierer ist in der Anweisung enthalten, die die Variable definiert, und wird verwendet, um die Datentypen von Klassen und Variablen vorzuverarbeiten.

Beispiel

public transient int limit = 55; //Nicht persistiert public int b; //Persisted

volatile-Modifizierer

Eine mit volatile modifizierte Membervariable zwingt Threads, den Wert dieser Membervariable bei jedem Zugriff erneut aus dem gemeinsamen Speicher zu lesen. Außerdem werden Threads, wenn sich die Membervariable ändert, gezwungen, den geänderten Wert zurück in den gemeinsamen Speicher zu schreiben. Auf diese Weise sehen zwei verschiedene Threads zu jedem Zeitpunkt immer denselben Wert für eine gegebene Membervariable.

Eine volatile Objektreferenz kann null sein.

Beispiel

public class MyRunnable implements Runnable { private volatile boolean active; public void run() { active = true; while (active) //Erste Zeile { //code } } public void stop() { active = false; //Zweite Zeile } }

Normalerweise wird in einem Thread die Methode run() aufgerufen (in einem von Runnable gestarteten Thread), und in einem anderen Thread wird die Methode stop() aufgerufen. WennErste Zeileder active-Wert im Puffer verwendet wird, dannZweite ZeileWenn der Wert von active false ist, wird die Schleife nicht beendet.

Aber im obigen Code haben wir volatile verwendet, um active zu ändern, daher wird die Schleife beendet.

Weitere Erweiterungen