Java 'public' Access Modifier

1. Übersicht

In diesem kurzen Artikel werden wir den öffentlichen Modifikator ausführlich behandeln und diskutieren, wann und wie er mit Klassen und Mitgliedern verwendet werden kann.

Darüber hinaus werden die Nachteile der Verwendung öffentlicher Datenfelder erläutert.

Einen allgemeinen Überblick über Zugriffsmodifikatoren finden Sie in unserem Artikel zu Zugriffsmodifikatoren in Java.

2. Wann wird der Modifikator für den öffentlichen Zugriff verwendet?

Öffentliche Klassen und Schnittstellen definieren zusammen mit öffentlichen Mitgliedern eine API. Es ist der Teil unseres Codes, den andere sehen und verwenden können, um das Verhalten unserer Objekte zu steuern.

Eine übermäßige Verwendung des öffentlichen Modifikators verstößt jedoch gegen das OOP-Kapselungsprinzip (Object-Oriented Programming) und hat einige Nachteile:

  • Dadurch wird die Größe einer API erhöht, was die Verwendung für Clients erschwert
  • Es wird immer schwieriger, unseren Code zu ändern, da sich Kunden darauf verlassen - zukünftige Änderungen können ihren Code beschädigen

3. Öffentliche Schnittstellen und Klassen

3.1. Öffentliche Schnittstellen

Eine öffentliche Schnittstelle definiert eine Spezifikation, die eine oder mehrere Implementierungen haben kann. Diese Implementierungen können entweder von uns bereitgestellt oder von anderen geschrieben werden.

Beispielsweise macht die Java-API die Verbindungsschnittstelle verfügbar, um Datenbankverbindungsvorgänge zu definieren, und überlässt die tatsächliche Implementierung jedem Anbieter. Zur Laufzeit erhalten wir die gewünschte Verbindung basierend auf dem Projekt-Setup:

Connection connection = DriverManager.getConnection(url);

Die Methode getConnection gibt eine Instanz einer technologie-spezifischen Implementierung zurück.

3.2. Öffentliche Klassen

Wir definieren öffentliche Klassen, damit Clients ihre Mitglieder durch Instanziierung und statische Referenzierung verwenden können:

assertEquals(0, new BigDecimal(0).intValue()); // instance member assertEquals(2147483647, Integer.MAX_VALUE); // static member 

Darüber hinaus können wir öffentliche Klassen für die Vererbung mithilfe des optionalen abstrakten Modifikators entwerfen . Wenn wir den Modifikator abstract verwenden , ist die Klasse wie ein Skelett, das Felder und vorimplementierte Methoden enthält, die jede konkrete Implementierung verwenden kann, sowie abstrakte Methoden, die jede Unterklasse implementieren muss.

Das Java-Sammlungsframework bietet beispielsweise die AbstractList- Klasse als Grundlage für die Erstellung benutzerdefinierter Listen:

public class ListOfThree extends AbstractList { @Override public E get(int index) { //custom implementation } @Override public int size() { //custom implementation } }

Wir müssen also nur die Methoden get () und size () implementieren . Andere Methoden wie indexOf () und includesAll ( ) sind für uns bereits implementiert.

3.3. Verschachtelte öffentliche Klassen und Schnittstellen

Ähnlich wie bei öffentlichen Klassen und Schnittstellen der obersten Ebene definieren verschachtelte öffentliche Klassen und Schnittstellen einen API-Datentyp. Sie sind jedoch in zweierlei Hinsicht besonders nützlich:

  • Sie zeigen dem API-Endbenutzer an, dass der einschließende Typ der obersten Ebene und seine eingeschlossenen Typen eine logische Beziehung haben und zusammen verwendet werden
  • Sie machen unsere Codebasis kompakter, indem sie die Anzahl der Quellcodedateien reduzieren, die wir verwendet hätten, wenn wir sie als Klassen und Schnittstellen der obersten Ebene deklariert hätten

Ein Beispiel ist die Karte . Eingabeschnittstelle von der Java-Kern-API:

for (Map.Entry entry : mapObject.entrySet()) { }

Etwas herstellen Karte . Die Eingabe einer verschachtelten Schnittstelle bezieht sich stark auf die Schnittstelle java.util.Map und hat uns vor dem Erstellen einer weiteren Datei im Paket java.util bewahrt.

Bitte lesen Sie den Artikel über verschachtelte Klassen für weitere Details.

4. Öffentliche Methoden

Mit öffentlichen Methoden können Benutzer vorgefertigte Vorgänge ausführen. Ein Beispiel ist die öffentliche toLowerCase- Methode in der String- API:

assertEquals("alex", "ALEX".toLowerCase());

Wir können eine öffentliche Methode sicher statisch machen, wenn sie keine Instanzfelder verwendet. Die parseInt- Methode aus der Integer- Klasse ist ein Beispiel für eine öffentliche statische Methode:

assertEquals(1, Integer.parseInt("1"));

Konstruktoren sind normalerweise öffentlich, damit wir Objekte instanziieren und initialisieren können, obwohl sie manchmal privat sind, wie in Singletons.

5. Öffentliche Felder

Öffentliche Felder ermöglichen das direkte Ändern des Status eines Objekts. Als Faustregel gilt, dass wir keine öffentlichen Felder verwenden sollten. Es gibt mehrere Gründe dafür, wie wir gleich sehen werden.

5.1. Thread-Safety

Using public visibility with non-final fields or final mutable fields is not thread-safe. We can't control changing their references or states in different threads.

Please check our article on thread-safety to learn more about writing thread-safe code.

5.2. Taking Actions on Modifications

We have no control over a non-final public field because its reference or state can be set directly.

Instead, it's better to hide the fields using a private modifier and use a public setter:

public class Student { private int age; public void setAge(int age) { if (age  150) { throw new IllegalArgumentException(); } this.age = age; } }

5.3. Changing the Data Type

Public fields, mutable or immutable, are part of the client's contract. It's harder to change the data representation of these fields in a future release because clients may need to refactor their implementations.

Indem wir den Feldern einen privaten Bereich geben und Accessoren verwenden, können wir die interne Darstellung flexibel ändern und gleichzeitig den alten Datentyp beibehalten:

 public class Student { private StudentGrade grade; //new data representation public void setGrade(int grade) { this.grade = new StudentGrade(grade); } public int getGrade() { return this.grade.getGrade().intValue(); } }

Die einzige Ausnahme für die Verwendung öffentlicher Felder ist die Verwendung statischer endgültiger unveränderlicher Felder zur Darstellung von Konstanten:

public static final String SLASH = "/";

6. Fazit

In diesem Tutorial haben wir gesehen, dass der öffentliche Modifikator zum Definieren einer API verwendet wird.

Außerdem haben wir beschrieben, wie eine übermäßige Verwendung dieses Modifikators die Möglichkeit einschränken kann, Verbesserungen an unserer Implementierung vorzunehmen.

Schließlich haben wir diskutiert, warum es eine schlechte Praxis ist, öffentliche Modifikatoren für Felder zu verwenden.

Und wie immer sind die Codebeispiele dieses Artikels auf GitHub verfügbar.