Wie kann man eine Java-Klasse unveränderlich machen, was ist die Notwendigkeit der Unveränderlichkeit und gibt es einen Vorteil, wenn man diese verwendet?
java
string
immutability
JavaUser
quelle
quelle
@Immutable
Anmerkung von jcabi-AspektenAntworten:
Was ist ein unveränderliches Objekt?
Ein unveränderliches Objekt ändert seinen Status nicht, nachdem es instanziiert wurde.
Wie mache ich ein Objekt unveränderlich?
Im Allgemeinen kann ein unveränderliches Objekt erstellt werden, indem eine Klasse definiert wird, für die keines ihrer Mitglieder verfügbar ist und für die keine Setter vorhanden sind.
Die folgende Klasse erstellt ein unveränderliches Objekt:
Wie im obigen Beispiel zu sehen ist, kann der Wert von
ImmutableInt
nur festgelegt werden, wenn das Objekt instanziiert wird, und wenn nur ein Getter (getValue
) vorhanden ist, kann der Status des Objekts nach der Instanziierung nicht geändert werden.Es muss jedoch darauf geachtet werden, dass alle Objekte, auf die das Objekt verweist, ebenfalls unveränderlich sind. Andernfalls kann der Status des Objekts möglicherweise geändert werden.
Wenn Sie beispielsweise
ArrayList
zulassen , dass ein Verweis auf ein Array oder über einen Getter abgerufen wird, kann sich der interne Status durch Ändern des Arrays oder der Sammlung ändern:Das Problem mit dem obigen Code ist, dass das
ArrayList
durch erhaltengetList
und manipuliert werden kann, was dazu führt, dass der Zustand des Objekts selbst geändert wird, daher nicht unveränderlich.Eine Möglichkeit, dieses Problem zu umgehen, besteht darin, eine Kopie eines Arrays oder einer Sammlung zurückzugeben, wenn diese von einem Getter aufgerufen wird:
Was ist der Vorteil der Unveränderlichkeit?
Der Vorteil der Unveränderlichkeit liegt in der Parallelität. Es ist schwierig, die Korrektheit in veränderlichen Objekten aufrechtzuerhalten, da mehrere Threads versuchen könnten, den Status desselben Objekts zu ändern, was dazu führt, dass einige Threads einen unterschiedlichen Status desselben Objekts sehen, abhängig vom Zeitpunkt der Lese- und Schreibvorgänge in das Objekt Objekt.
Durch ein unveränderliches Objekt kann sichergestellt werden, dass alle Threads, die das Objekt betrachten, denselben Status sehen, da sich der Status eines unveränderlichen Objekts nicht ändert.
quelle
return Collections.unmodifiableList(list);
eine schreibgeschützte Ansicht der Liste zurückgeben.final
werden. Andernfalls kann es mit einer Setter-Methode (oder anderen Arten von Mutationsmethoden und veränderlichen Feldern) erweitert werden.final
wenn die Klasse nurprivate
Felder hat , da von Unterklassen aus nicht auf sie zugegriffen werden kann.Zusätzlich zu den bereits gegebenen Antworten würde ich empfehlen, über Unveränderlichkeit in Effective Java, 2. Ausgabe, zu lesen, da einige Details leicht zu übersehen sind (z. B. defensive Kopien). Plus, effektive Java 2nd Ed. ist ein Muss für jeden Java-Entwickler.
quelle
Sie machen eine Klasse unveränderlich wie folgt:
Im Folgenden sind die Anforderungen aufgeführt, um eine Java-Klasse unveränderlich zu machen:
final
(damit untergeordnete Klassen nicht erstellt werden können)final
(damit wir den Wert nach der Objekterstellung nicht ändern können)Unveränderliche Klassen sind nützlich, weil
- sie threadsicher sind.
- Sie drücken auch etwas Tiefes an Ihrem Design aus: "Kann das nicht ändern.", Wenn es zutrifft, ist es genau das, was Sie brauchen.
quelle
Unveränderlichkeit kann hauptsächlich auf zwei Arten erreicht werden:
final
Instanzattributen, um eine Neuzuweisung zu vermeidenVorteile der Unveränderlichkeit sind die Annahmen, die Sie für dieses Objekt treffen können:
quelle
Unveränderliche Klassen können nach der Instanziierung keine Werte neu zuweisen. Der Konstruktor weist seinen privaten Variablen Werte zu. Bis das Objekt null wird, können Werte aufgrund der Nichtverfügbarkeit von Setter-Methoden nicht geändert werden.
unveränderlich zu sein sollte folgendes befriedigen,
Vorteile: Unveränderliche Objekte enthalten ihre initialisierten Werte, bis sie sterben.
Java-unveränderliche-Klassen-Kurznotiz
quelle
Unveränderliche Klassen sind solche, deren Objekte nach der Erstellung nicht mehr geändert werden können.
Unveränderliche Klassen sind nützlich für
Beispiel
String-Klasse
Codebeispiel
quelle
@ Jack, endgültige Felder und Setter in der Klasse zu haben, macht die Klasse nicht unveränderlich. Das endgültige Schlüsselwort stellt nur sicher, dass eine Variable niemals neu zugewiesen wird. Sie müssen eine tiefe Kopie aller Felder in Getter-Methoden zurückgeben. Dadurch wird sichergestellt, dass nach dem Abrufen eines Objekts von der Getter-Methode der interne Status des Objekts nicht gestört wird.
quelle
Eine andere Möglichkeit, unveränderliche Objekte zu erstellen, ist die Verwendung der Immutables.org- Bibliothek:
quelle
Als nicht-englischer Muttersprachler mag ich die übliche Interpretation von "unveränderlicher Klasse" als "konstruierte Klassenobjekte sind unveränderlich" nicht. Vielmehr neige ich selbst dazu, dies als "das Klassenobjekt selbst ist unveränderlich" zu interpretieren.
Das heißt, "unveränderliche Klasse" ist eine Art unveränderliches Objekt. Der Unterschied besteht darin, zu beantworten, was der Nutzen ist. Meines Wissens / meiner Interpretation nach verhindert eine unveränderliche Klasse, dass ihre Objekte Änderungen am Laufzeitverhalten vornehmen.
quelle
Eine unveränderliche Klasse ist einfach eine Klasse, deren Instanzen nicht geändert werden können.
Alle in jeder Instanz enthaltenen Informationen sind für die Lebensdauer des Objekts festgelegt, sodass niemals Änderungen beobachtet werden können.
Unveränderliche Klassen sind einfacher zu entwerfen, zu implementieren und zu verwenden als veränderbare Klassen.
Befolgen Sie diese fünf Regeln, um eine Klasse unveränderlich zu machen:
Geben Sie keine Methoden an, die den Status des Objekts ändern
Stellen Sie sicher, dass die Klasse nicht erweitert werden kann.
Machen Sie alle Felder endgültig.
Machen Sie alle Felder privat.
Stellen Sie den exklusiven Zugriff auf veränderbare Komponenten sicher.
Unveränderliche Objekte sind von Natur aus threadsicher. Sie erfordern keine Synchronisation.
Unveränderliche Objekte können frei geteilt werden.
Unveränderliche Objekte sind großartige Bausteine für andere Objekte
quelle
Die meisten Antworten hier sind gut, und einige haben die Regeln erwähnt, aber ich finde es gut, in Worte zu fassen, warum und wann wir diese Regeln befolgen müssen. Also gebe ich die folgende Erklärung
Und wenn wir versuchen, Setter für diese endgültigen Variablen zu verwenden, gibt der Compiler natürlich einen Fehler aus.
Müssen wir die Klasse als "endgültig" deklarieren?
1. Nur primitive Mitglieder haben: Wir haben kein Problem Wenn die Klasse nur primitive Mitglieder hat, müssen wir die Klasse nicht als endgültig deklarieren.
2. Objekte als Mitgliedsvariablen haben: Wenn wir Objekte als Mitgliedsvariablen haben, müssen wir die Mitglieder dieser Objekte ebenfalls endgültig machen. Das heißt, wir müssen tief im Baum durchqueren und alle Objekte / Grundelemente als endgültig festlegen, was möglicherweise nicht immer möglich ist. Die Problemumgehung besteht also darin, die Klasse endgültig zu machen, wodurch die Vererbung verhindert wird. Es ist also keine Frage, ob Unterklassen Getter-Methoden überschreiben.
quelle
Wie kann man eine Java-Klasse unveränderlich machen?
Ab JDK 14+ mit JEP 359 können wir "
records
" verwenden. Es ist die einfachste und stressfreieste Art, unveränderliche Klassen zu erstellen.Eine Datensatzklasse ist ein flach unveränderlicher , transparenter Träger für einen festen Satz von Feldern, der als Datensatz bezeichnet
components
wird und einestate
Beschreibung für den Datensatz enthält. Jedescomponent
führt zu einemfinal
Feld, das den angegebenen Wert enthält, und eineraccessor
Methode zum Abrufen des Werts. Der Feldname und der Zugriffsname stimmen mit dem Namen der Komponente überein.Betrachten wir das Beispiel zum Erstellen eines unveränderlichen Rechtecks
Keine Notwendigkeit, einen Konstruktor zu deklarieren, keine Notwendigkeit, equals & hashCode-Methoden zu implementieren. Nur alle Datensätze benötigen einen Namen und eine Statusbeschreibung.
Wenn Sie den Wert während der Objekterstellung überprüfen möchten, müssen wir den Konstruktor explizit deklarieren.
Der Datensatzkörper kann statische Methoden, statische Felder, statische Initialisierer, Konstruktoren, Instanzmethoden und verschachtelte Typen deklarieren.
Instanzmethoden
statische Felder, Methoden
Da state Teil der Komponenten sein sollte, können wir Datensätzen keine Instanzfelder hinzufügen. Wir können jedoch statische Felder und Methoden hinzufügen:
Was ist das Bedürfnis nach Unveränderlichkeit und hat es einen Vorteil, dies zu nutzen?
Zuvor veröffentlichte Antworten sind gut genug, um die Notwendigkeit der Unveränderlichkeit und ihrer Vorteile zu rechtfertigen
quelle