Ich sehe die unveränderlichsten POJOs so geschrieben:
public class MyObject {
private final String foo;
private final int bar;
public MyObject(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
public String getFoo() {
return foo;
}
public int getBar() {
return bar;
}
}
Dennoch neige ich dazu, sie so zu schreiben:
public class MyObject {
public final String foo;
public final int bar;
public MyObject(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
}
Beachten Sie, dass die Referenzen endgültig sind, sodass das Objekt noch unveränderlich ist. Dadurch kann ich weniger Code schreiben und kürzeren Zugriff (mit 5 Zeichen: get
und ()
).
Der einzige Nachteil, den ich sehen kann, ist, dass Sie die Implementierung von getFoo()
Down-the-Road ändern möchten, um etwas Verrücktes zu tun, was Sie nicht können. Realistisch gesehen geschieht dies jedoch nie, weil das Objekt unveränderlich ist. Sie können dies während der Instantiierung überprüfen, unveränderliche Verteidigungskopien während der Instantiierung erstellen (siehe ImmutableList
z. B. Guave ) und die foo
oder bar
-Objekte für den get
Anruf vorbereiten .
Gibt es irgendwelche Nachteile, die ich vermisse?
BEARBEITEN
Ich vermute, ein weiterer Nachteil, den ich vermisse, ist die Verwendung von Serialisierungsbibliotheken mit Reflektion über Methoden, die mit get
oder beginnen is
, aber das ist eine ziemlich schreckliche Praxis ...
quelle
final
macht eine Variable nicht zum unveränderlichen Objekt. Normalerweise verwende ich ein Design, in dem ichfinal
vor dem Erstellen eines Rückrufs Felder definiere , damit der Rückruf auf diese Felder zugreifen kann. Es können natürlich alle Methoden einschließlich aller Methoden aufgerufensetX
werden.String
,int
oderMyObject
. In der ersten Versionfinal
soll nur sichergestellt werden, dass andere Methoden als der Konstruktor innerhalb der Klasse dies beispielsweise nicht versuchenbar = 7;
. In der zweiten Versionfinal
ist notwendig , die Verbraucher zu verhindern , dass zu tun:MyObject x = new MyObject("hi", 5); x.bar = 7;
.Object
ist also immer noch unveränderlich. " Ist irreführendfinal Object
. Entschuldigung für das Missverständnis.myObj.getFoo().setFrob(...)
.Antworten:
Vier Nachteile, die ich mir vorstellen kann:
Das heißt, Ihre Version ist definitiv prägnanter. Wenn dies eine spezialisierte Klasse wäre, die nur innerhalb eines bestimmten Pakets verwendet wird (vielleicht ist der Umfang eines Pakets hier eine gute Idee), dann könnte ich dies für einmalige Fälle in Betracht ziehen. Aber ich würde keine wichtigen APIs wie dieses verfügbar machen.
quelle
Werde auch die Getter / Setter los und es geht dir gut!
Dies ist ein sehr kontroverses Thema unter Java-Programmierern.
Wie auch immer, es gibt zwei Situationen, in denen ich öffentliche Variablen anstelle (!) Von Gettern / Setzern verwende:
quelle
Mit den Worten des Laien:
quelle
Ein möglicher Nachteil, den ich sofort sehe, ist, dass Sie an die interne Darstellung der Daten in der Klasse gebunden sind. Dies ist wahrscheinlich keine große Sache, aber wenn Sie die Setter verwenden und entscheiden, dass foo und bar von einer anderen Klasse zurückgegeben werden, die an einer anderen Stelle definiert wurde, müssen die Klassen, die MyObject verbrauchen, nicht geändert werden. Sie müssten nur MyObject berühren. Wenn Sie jedoch die nackten Werte verwenden, müssen Sie Ihr MyObject, das ich verwendet habe, überall anfassen.
quelle