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: getund ()).
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 ImmutableListz. B. Guave ) und die foooder bar-Objekte für den getAnruf 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 getoder beginnen is, aber das ist eine ziemlich schreckliche Praxis ...
String, intoder MyObject. In der ersten Version finalsoll nur sichergestellt werden, dass andere Methoden als der Konstruktor innerhalb der Klasse dies beispielsweise nicht versuchen bar = 7;. In der zweiten Version finalist notwendig , die Verbraucher zu verhindern , dass zu tun: MyObject x = new MyObject("hi", 5); x.bar = 7;.
Objectist also immer noch unveränderlich. " Ist irreführend final Object. Entschuldigung für das Missverständnis.
myObj.getFoo().setFrob(...).
finalmacht eine Variable nicht zum unveränderlichen Objekt. Normalerweise verwende ich ein Design, in dem ichfinalvor 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 aufgerufensetXwerden.