1. Einführung in unveränderliche Kategorien
Unveränderliche Klasse: Die sogenannte unveränderliche Klasse bedeutet, dass nach einer Instanz dieser Klasse der variable Mitgliedswert nicht geändert werden kann. Zum Beispiel viele unveränderliche Klassen, die mit JDK geliefert werden: Interger, Long und String usw.
Variablen Klassen: Im Vergleich zu unveränderlichen Klassen können veränderliche Klassen nach dem Erstellen von Instanzen ihre Mitgliedervariablenwerte ändern. Die meisten in der Entwicklung erstellten Klassen gehören zu veränderlichen Klassen.
2. Vorteile unveränderlicher Klassen
Nachdem wir über den Unterschied zwischen veränderlichen Klassen und unveränderlichen Klassen gesprochen haben, müssen wir weiter verstehen, warum es unveränderliche Klassen gibt? Welche Vorteile bringt ein solches Feature zu Java?
1. Fadensicherheit
Unveränderliche Objekte sind threadsicher und können zwischen Threads geteilt werden. Es besteht keine Notwendigkeit, spezielle Mechanismen zu verwenden, um Synchronisationsprobleme sicherzustellen, da der Wert des Objekts nicht geändert werden kann. Es kann die Möglichkeit von gleichzeitigen Fehlern verringern, da es nicht erforderlich ist, einige Sperrmechanismen zu verwenden, um Probleme mit der Speicherkonsistenz zu gewährleisten, wodurch auch die Synchronisationsaufwand reduziert wird.
2. Einfach zu konstruieren, zu verwenden und zu testen
3 ....
Unveränderliche Klassenentwurfsmethode
Für Design unveränderliche Klassen fasse ich die folgenden Prinzipien persönlich zusammen:
1. Fügen Sie der Klasse einen endgültigen Modifikator hinzu, um sicherzustellen, dass die Klasse nicht geerbt wird.
Wenn eine Klasse vererbt werden kann, zerstört sie den Unveränderlichkeitsmechanismus der Klasse, solange die Erbschaftsklasse die Methoden der Elternklasse überschreibt und die Erbschaftsklasse den Variablenwert der Mitgliedsänderung ändern kann, dann kann nicht garantiert werden, ob die aktuelle Klasse veränderlich ist.
2. Stellen Sie sicher, dass alle Mitgliedsvariablen privat sein müssen und die endgültige Änderung hinzugefügt wird
Auf diese Weise stellt sicher, dass Mitgliedsvariablen unveränderlich sind. Aber es reicht nicht aus, denn wenn es sich um eine Objektmitgliedvariable handelt, ist es möglich, ihren Wert extern zu ändern. Der vierte Punkt macht diesen Mangel wieder wett.
3. Es werden keine Methoden bereitgestellt, um die Mitgliedsvariablen zu ändern, einschließlich Setzer
Vermeiden Sie es, den Wert von Mitgliedsvariablen durch andere Schnittstellen zu ändern und unveränderliche Merkmale zu zerstören.
V.
Wenn das vom Konstruktor übergebene Objekt direkt der Elementvariablen zugeordnet ist, kann es weiterhin geändert werden, indem das eingehende Objekt geändert wird, wodurch der Wert der internen Variablen geändert wird. Zum Beispiel:
public Final Class Immutabledemo {private final int [] myarray; public immutabledemo (int [] array) {this.myArray = array; // falsch } }Diese Methode kann die Unveränderlichkeit nicht garantieren. Myarray und Array zeigen auf die gleiche Speicheradresse. Benutzer können den Wert innerhalb von MyArray ändern, indem sie den Wert des Array -Objekts außerhalb von Immutabledemo ändern.
Um sicherzustellen, dass der interne Wert nicht geändert wird, kann die Tiefenkopie verwendet werden, um einen neuen Speicher zu erstellen, um den eingehenden Wert zu speichern. Richtige Möglichkeit, dies zu tun:
public Final Class Myimmutabledemo {private final int [] myarray; public myimmutabledemo (int [] array) {this.myArray = array.clone (); }}5. Geben Sie das Objekt in der Getter -Methode nicht direkt zurück, sondern klonen Sie das Objekt und geben Sie die Kopie des Objekts zurück.
Dieser Ansatz verhindert auch das Leckagen von Objekten und verhindert den direkten Betrieb von Mitgliedervariablen, nachdem interne mutable Elementelemente über Getters erhalten wurden, was zu Änderungen der Mitgliedsvariablen führt.
Iv. Unveränderlichkeit von String -Objekten
Das String -Objekt kann nach der Erstellung der Speicher nicht geändert werden. Die Schaffung unveränderlicher Objekte entspricht im Allgemeinen den oben genannten 5 Prinzipien. Schauen wir uns an, wie der String -Code implementiert wird.
öffentliche endgültige Klasse StringImplements java.io.serializable, vergleichbar <string>, charsequence {/** Der Wert wird für den Zeichenspeicher verwendet. */privater endgültiger Zeichen [];/** Der Offset ist der erste Index des verwendeten Speichers. */Private Final INT -Offset;/** Die Anzahl ist die Anzahl der Zeichen in der Zeichenfolge. */private endgültige int count;/** cache den Hash -Code für die Zeichenfolge*/private int Hash; // standardmäßig 0..public String (char value []) {this.Value = arrays.copyof (value, value.length); // Deep Copy Operation} ... public char [] toCharArray () {// Arrays.copyof kann aufgrund der Klasseninitialisierungsreihenfolge problematchar;Wie im obigen Code gezeigt, können die folgenden Entwurfsdetails beobachtet werden:
1. Die Stringklasse wird durch endgültig geändert und kann nicht vererbt werden
2. Alle Mitglieder der String werden als private Variablen festgelegt
3. Der Wert Setter existiert nicht
4. und Wert setzen und auf das Finale versetzen.
5. Kopieren Sie ihn beim Übergeben eines variablen Array -Wertes [], anstatt den Wert [] direkt in die interne Variable zu kopieren.
6. Wenn Sie den Wert erhalten, gibt es die Objektreferenz nicht direkt zurück, sondern die Kopie des Objekts zurück.
Dies steht im Einklang mit den Eigenschaften des oben zusammengefassten invarianten Typs und stellt auch sicher, dass der String -Typ eine unveränderliche Klasse ist.
5. Vor- und Nachteile der Unveränderlichkeit von String -Objekten
Aus der vorherigen Abschnittsanalyse sind String -Daten unveränderlich. Was sind also die Vorteile einer solchen Funktion? Ich habe es wie folgt zusammengefasst:
1. Anforderungen für String Constant Pools.
Saiten konstante Pools können einige Charakterkonstanten im konstanten Pool wiederverwenden, wodurch das gleiche Objekt jedes Mal nachgebildet und Speicherplatz speichert. Wenn die Zeichenfolge jedoch variabel ist, weist die Zeichenfolge des gleichen Inhalts auch auf denselben Speicherraum des konstanten Pools hin. Wenn eine Variable den Wert dieses Speichers ändert, ändert sich auch die anderen durchquerten Werte. Daher entspricht es nicht der ursprünglichen Absicht eines konstanten Pooldesigns.
2. Überlegungen zur Sicherheit von Faden.
Die gleiche String -Instanz kann von mehreren Threads gemeinsam genutzt werden. Auf diese Weise besteht keine Synchronisation aufgrund von Sicherheitsproblemen mit Thread -Sicherheit. Saiten sind fadensicher.
3. Klassenlader müssen Zeichenfolgen verwenden, und die Unveränderlichkeit bietet Sicherheit, damit die richtige Klasse geladen wird. Wenn Sie beispielsweise die Java.sql.Connection -Klasse laden möchten und dieser Wert in myHacked.connection geändert wird, wird Ihre Datenbank unbekannt beschädigt.
4. unterstützen Hash Mapping und Caching.
Da Saiten unveränderlich sind, wird der Hashcode zwischengespeichert, wenn er erstellt wird und nicht neu berechnet werden muss. Dies macht Saiten sehr geeignet als Schlüssel in der Karte, und die Verarbeitungsgeschwindigkeit von Saiten ist schneller als andere Schlüsselobjekte. Aus diesem Grund verwenden Schlüssel in HashMap häufig Saiten.
Mangel:
1. Wenn es erforderlich ist, den Wert des String -Objekts zu ändern, wird eine große Anzahl von String -Objekten erstellt.
6. Ist das String -Objekt wirklich unveränderlich?
Obwohl das String -Objekt den Wert auf endgültig festlegt, stellt es auch sicher, dass seine Mitgliedsvariablen durch verschiedene Mechanismen unveränderlich sind. Es kann jedoch immer noch durch den Reflexionsmechanismus geändert werden. Zum Beispiel:
// Erstellen Sie die Zeichenfolge "Hello World" und weisen Sie sie der Referenz SSTRING S = "Hello World" zu; System.out.println ("S =" + s); // Hello World // Erhalten Sie das Wertfeldfeld in der String -Klasse Field ValueFieldOfstring = string.class.getDeclaredfield ("Wert"); // Ändern Sie die Zugriffsgenehmigung des Wertattributungswerts. '_'; System.out.println ("S =" + s); // Hello_worldDas Druckergebnis ist:
S = Hallo Welten = Hallo_World
Es wurde festgestellt, dass sich der Wert der String geändert hat. Das heißt, das sogenannte "unveränderliche" Objekt kann durch Reflexion geändert werden.
Zusammenfassen
Eine unveränderliche Klasse ist der Wert des Mitgliedsquellens, der nach dem Erstellen der Instanz nicht geändert werden kann. Mit dieser Funktion können unveränderliche Klassen mit Thread-sichere Funktionen bereitstellen, aber auch den Overhead der Objekterstellung bringt. Jede Änderung des Attributs besteht darin, ein neues Objekt nachzubilden. JDK bietet auch viele unveränderliche Klassen wie Ganzzahl, Doppel, String usw. Die unveränderlichen Merkmale der String erfüllen hauptsächlich die Anforderungen von konstantem Pooling, Gewindesicherheit und Klassenbelastung. Der rationale Einsatz unveränderlicher Klassen kann große Vorteile bringen.
Das obige ist der unveränderliche Mechanismus der Java (unveränderlich) und die Unveränderlichkeit von String (empfohlen), die Ihnen vom Herausgeber vorgestellt wurden. Ich hoffe, es wird Ihnen hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Editor wird Ihnen rechtzeitig antworten. Vielen Dank für Ihre Unterstützung auf der Wulin.com -Website!