Sind Javas öffentliche Bereiche zu diesem Zeitpunkt nur ein tragischer historischer Konstruktionsfehler? [geschlossen]

17

Es scheint an dieser Stelle eine Java-Orthodoxie zu sein, dass man grundsätzlich niemals öffentliche Felder für den Objektzustand verwenden sollte. (Ich stimme dem nicht unbedingt zu, aber das ist für meine Frage nicht relevant.) Wäre es angesichts dessen richtig zu sagen, dass Javas öffentliche Felder aus heutiger Sicht ein Fehler des Sprachdesigns waren? Oder gibt es ein rationales Argument dafür, dass sie auch heute noch ein nützlicher und wichtiger Bestandteil der Sprache sind?

Vielen Dank!

Update: Ich kenne die eleganteren Ansätze wie C #, Python, Groovy usw. Ich suche nicht direkt nach diesen Beispielen. Ich frage mich wirklich nur, ob sich noch jemand tief in einem Bunker befindet, der darüber murmelt, wie wundervoll öffentliche Felder wirklich sind und wie die Massen nur Schafe usw. sind.

Update 2: Eindeutig statische öffentliche Endfelder sind die Standardmethode zum Erstellen öffentlicher Konstanten. Ich bezog mich mehr auf die Verwendung öffentlicher Felder für den Objektzustand (sogar den unveränderlichen Zustand). Ich denke, es scheint ein Konstruktionsfehler zu sein, öffentliche Felder für Konstanten zu verwenden, aber nicht für den Zustand. Die Regeln einer Sprache sollten natürlich durch Syntax und nicht durch Richtlinien durchgesetzt werden.

Avi Flax
quelle
2
Was ist Ihre Grundlage, dass sie in der Tat ein Fehler sind?
Aaron McIver
1
Gibt es jetzt eine andere Möglichkeit, symbolische konstante Ausdrücke in Java zu erstellen?
Edward Strange
@ Aaron Ich habe nicht gesagt, dass sie ein Fehler sind, ich habe gesagt, dass ich es zu diesem Zeitpunkt als orthodox empfunden habe, dass man niemals öffentliche Felder benutzen sollte. Diese Wahrnehmung mag falsch sein, aber es ist in der Tat das, was ich wahrgenommen habe.
Avi Flax
@ Crazy Eddie Ich habe diese Verwendung vergessen, ich dachte mehr über die häufigere Verwendung von Feldern nach, Zustand. Ich werde die Frage bearbeiten.
Avi Flax

Antworten:

14

Ich mag sie, solange das Feld endgültig ist und nur intern in der Anwendung verwendet wird und nicht in einer API für andere Anwendungen verfügbar gemacht wird. Dies hält Ihren Code kürzer und lesbarer.

Sie sollten keine öffentlichen Felder in einer API verfügbar machen, da Sie durch das Bereitstellen öffentlicher Felder auch die Implementierung verfügbar machen. Wenn Sie es getXXX()stattdessen als Methode verfügbar machen, können Sie die Implementierung ändern, ohne die API-Schnittstelle zu ändern. Beispielsweise könnten Sie den Wert von einem Remote-Dienst ändern und abrufen, aber die Anwendungen, die die API verwenden, müssen dies nicht wissen.

Dies ist ein praktikables Design für public finalFelder in unveränderlichen Klassen.

Aus effektivem Java :

Punkt 14: Verwenden Sie in öffentlichen Klassen Accessormethoden und keine öffentlichen Felder

... wenn eine Klasse paket-privat oder eine private verschachtelte Klasse ist, ist es nicht von Natur aus falsch, ihre Datenfelder bereitzustellen. Dieser Ansatz erzeugt weniger Unordnung als der Zugriffsmethodenansatz.

Während es für eine öffentliche Klasse nie eine gute Idee ist, Felder direkt freizulegen, ist es weniger schädlich, wenn die Felder unveränderlich sind.

Siehe auch Warum sollte ich keine unveränderlichen POJOs anstelle von JavaBeans verwenden?

Jonas
quelle
Ich frage mich nur, was sind Ihre Gründe, warum Sie es nicht in einer API verfügbar machen?
Steven Jeuris
2
@Steven: Da Sie öffentliche Felder verfügbar machen, legen Sie auch die Implementierung offen. Wenn Sie es getXXX()stattdessen als Methode verfügbar machen, können Sie die Implementierung ändern, ohne die API-Schnittstelle zu ändern. Sie können den Wert beispielsweise von einem Remotedienst ändern und abrufen, aber die Anwendungen, die die API verwenden, müssen dies nicht wissen.
Jonas
@Jonas: Das sind in der Regel überhaupt keine Kandidaten für Konstanten.
Steven Jeuris
@Steven: Ich spreche nicht von Konstanten, sondern von öffentlichen Endfeldern in unveränderlichen Klassen. Siehe z. B. Warum sollte ich keine unveränderlichen POJOs anstelle von JavaBeans verwenden?
Jonas
@Jonas: Das ist auch ein guter Anwendungsfall! Vielleicht ist es hilfreich, Ihre Antwort ein wenig zu aktualisieren, um dies zu klären.
Steven Jeuris
9

Die Verwendung von Get / Set-Methodenpaaren ist der tragische historische Konstruktionsfehler. Ich kann mir keine andere Sprache vorstellen, die Eigenschaften so wörtlich und ineffizient implementiert.

Kevin Cline
quelle
1
Zwar ist dies etwas tangential zum Punkt der Frage, der (im Wesentlichen) darin besteht, dass es angesichts der Wahl zwischen set / get-Methoden und öffentlichen Feldern gute Gründe gibt, in bestimmten Situationen Felder zu bevorzugen. Dass andere Sprachen bessere Lösungen für das Problem bieten, scheint mir irrelevant zu sein.
Jules
5

Ich denke, dass öffentliche Felder für eine Klasse in Ordnung sind, die im Wesentlichen ein Wertetyp wie eine komplexe Zahl oder ein Punkt ist, bei dem die Klasse nur primitive Typen wie eine C-artige Struktur gruppiert und möglicherweise einige Operatoren definiert.

Karl Bielefeldt
quelle
2
java.awt.Pointund Freunde sind ein Albtraum.
Tom Hawtin - Tackline
@ TomHawtin-tackline: Das Problem dabei Pointist, dass es nicht eindeutig ist, ob eine Variable vom Typ PointStandorte einkapseln soll oder die Identität einer Entität mit einem Standort, der sich ändern kann. Konzeptionell würde ich Code, der herumreicht Point, als ähnlich wie Code ansehen, der um Arrays herumreicht.
Supercat
Wenn ich also ein bekomme Pointund es ändere, sollte ich erwarten, dass das Objekt, auf das es verweist, auf dem Bildschirm sauber aktualisiert wird? Nein, das Problem Pointist, dass es veränderlich ist. Wir hatten String/ StringBufferaber die Idee schien nicht durchzukommen. / Das Weitergeben von Arrays hat ähnliche Probleme.
Tom Hawtin - Tackline
5

Es ist immer noch nützlich, öffentliche Konstanten zu definieren. Z.B

public static final int DAYS_IN_WEEK = 7;

Ziehen Sie jedoch nach Möglichkeit immer noch Aufzählungen vor . Z.B

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY 
}

Es ist auch nützlich, einfache Strukturklassen zu simulieren . Kein Grund, für jedes Feld einen Getter und Setter zu erstellen, wenn sie doch alle öffentlich sind.

class Point
{
    public int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
Steven Jeuris
quelle
Andererseits würden viele argumentieren, dass Strukturen in einer Sprache wie Java keinen Platz haben ...
1
@delnan: Sie sind fast identisch mit JavaBeans, aber JavaBeans ist viel ausführlicher und nicht threadsicher. Siehe Warum sollte ich keine unveränderlichen POJOs anstelle von JavaBeans verwenden?
Jonas
Einige Android-spezifische Beobachtungen: Aufzählungen sind langsamer zu bewerten als Ints und sollten vermieden werden. Auch Felder, auf die Setter und Getter in engen Schleifen häufig zugreifen, können davon profitieren, öffentlich zu sein.
Nagler
2

Bevor sich IDEs verbreiteten, war es ein mächtiges Werkzeug, alle Ihre Felder öffentlich zu machen, um schnell Prototypen / Proofs von Konzepten zu erstellen.

Heutzutage gibt es kaum eine Entschuldigung dafür, wenn Sie mit einem Mausklick ein Getter / Setter-Paar generieren können.

biziclop
quelle
4
10 public finalFelder sind jedoch lesbarer als 10 getXXX()Methoden.
Jonas
1
@Jonas Ja, aber wir reden hier nicht über letzte Felder. Wenn Ihre öffentlichen Endfelder ebenfalls statisch sind, sind sie Konstanten, und ein constSchlüsselwort wäre ausreichend. Wenn sie nicht statisch sind, stellen sie eine schwerwiegende Verletzung der Kapselung dar.
biziclop
3
@biziclop laut Wikipedia : "Obwohl als Schlüsselwort in Java reserviert, wird const nicht verwendet und hat keine Funktion"
Avi Flax
@Avi Flax Ja, aber es hätte verwendet werden können, um Konstanten zu markieren, sodass Konstanten nicht mehr als öffentliche Felder deklariert werden müssen.
biziclop
2
Angenommen, ein Getter / Setter-Paar ist überhaupt angemessen. Es ist oft nicht.
David Thornley
2

Dies ist subjektiv, aber meiner Meinung nach ist der gesamte öffentliche / private Begriff veraltet und rückständig.

In Python gibt es keine öffentlichen / privaten; alles ist grundsätzlich öffentlich. Hat nicht viele Probleme verursacht.

In Java neigen Sie dazu, sinnlose Getter / Setter für jedes Feld zu erstellen, um die Sünde zu vermeiden, sie als "öffentlich" zu kennzeichnen. (IMHO, wenn Sie feststellen, dass Sie das tun, sollten Sie sie nur öffentlich markieren).

hasen
quelle
Mit Python können Sie Dinge als privat markieren, indem Sie den Namen __ voranstellen. Es ist nicht 100% privat, da es immer noch Möglichkeiten gibt, auf diese Variablen und Methoden zuzugreifen, aber in C # können Sie ähnliche Dinge mit Reflektion tun.
Adam Lear