In Java bedeutet Unveränderlichkeit, dass der interne Zustand eines Objekts nach der Erstellung nicht mehr geändert werden kann. Unveränderliche Klassen in Java bieten viele Vorteile wie Thread-Sicherheit, einfaches Debuggen und vieles mehr. In Java alle Wrapper-Klassen (wie Integer Boolean Byte Short) und die String-Klasse ist unveränderlich. Wir können auch unsere eigene unveränderliche Klasse erstellen.
In diesem Artikel erfahren wir:
- Was Unveränderlichkeit bedeutet
- Warum es nützlich ist
- So erstellen Sie unsere eigene unveränderliche Klasse
- Warum Deep Copying wichtig ist
- Welche Einschränkungen gibt es bei Java-Datensatztypen?
Was ist eine unveränderliche Klasse?
Eine unveränderliche Klasse ist eine Klasse, deren Objekte nach ihrer Erstellung nicht mehr geändert werden können. Wenn wir Änderungen vornehmen, entsteht ein neues Objekt. Diese Methode wird in gleichzeitigen Anwendungen verwendet.
Regeln zum Erstellen einer unveränderlichen Klasse
- Die Klasse muss als deklariert werden Finale sodass keine untergeordneten Klassen erstellt werden können.
- Datenelemente in der Klasse müssen deklariert werden Privat sodass ein direkter Zugriff nicht möglich ist.
- Datenelemente in der Klasse müssen als deklariert werden Finale sodass wir ihren Wert nach der Objekterstellung nicht ändern können.
- Ein parametrisierter Konstruktor sollte alle Felder initialisieren, die a ausführen tiefe Kopie sodass Datenelemente nicht mit einer Objektreferenz geändert werden können.
- Deep Copy von Objekten sollte in den Getter-Methoden durchgeführt werden, um eine Kopie zurückzugeben, anstatt die eigentliche Objektreferenz zurückzugeben.
Notiz : Es sollte keine Setter geben oder einfacher ausgedrückt, es sollte keine Option zum Ändern des Werts der Instanzvariablen geben.
enthält in string
Beispiel: Unveränderliche Klassenimplementierung
Student.java
Java// Java Program to Create An Immutable Class import java.util.HashMap; import java.util.Map; // declare the class as final final class Student { // make fields private and final private final String name; private final int regNo; private final Map<String String> metadata; // initialize all fields via constructor public Student(String name int regNo Map<String String> metadata) { this.name = name; this.regNo = regNo; // deep copy of mutable object (Map) Map<String String> tempMap = new HashMap<>(); for (Map.Entry<String String> entry : metadata.entrySet()) { tempMap.put(entry.getKey() entry.getValue()); } this.metadata = tempMap; } // only provide getters (no setters) public String getName() { return name; } public int getRegNo() { return regNo; } // return deep copy to avoid exposing internal state public Map<String String> getMetadata() { Map<String String> tempMap = new HashMap<>(); for (Map.Entry<String String> entry : this.metadata.entrySet()) { tempMap.put(entry.getKey() entry.getValue()); } return tempMap; } }
In diesem Beispiel haben wir eine letzte Klasse mit dem Namen erstellt Student. Es verfügt über drei letzte Datenelemente, einen parametrisierten Konstruktor und Getter-Methoden. Bitte beachten Sie, dass es hier keine Setter-Methode gibt. Beachten Sie außerdem, dass wir kein Deep Copy oder Klonen von Datenelementen von Wrapper-Typen durchführen müssen, da diese bereits unveränderlich sind.
Geeks.java:
Javaimport java.util.HashMap; import java.util.Map; public class Geeks { public static void main(String[] args) { // create a map and adding data Map<String String> map = new HashMap<>(); map.put('1' 'first'); map.put('2' 'second'); // create an immutable Student object Student s = new Student('GFG' 101 map); // accessing data System.out.println(s.getName()); System.out.println(s.getRegNo()); System.out.println(s.getMetadata()); // try to modify the original map map.put('3' 'third'); System.out.println(s.getMetadata()); // try to modify the map returned by getMetadata() s.getMetadata().put('4' 'fourth'); System.out.println(s.getMetadata()); } }
Auch nach der Änderung der ursprünglichen oder zurückgegebenen Map bleibt der interne Status des Student-Objekts unverändert. Dies bestätigt das Unveränderlichkeitskonzept.
Java-Punkt
Ausgabe:
GFG
101
{1=first 2=second}
{1=first 2=second}
{1=first 2=second}
Einschränkung des Java-Datensatzes mit veränderlichen Feldern
Java 14 eingeführt aufzeichnen . Dies ist eine klare und prägnante Möglichkeit, unveränderliche Klassen zu definieren:
record Student(String name int regNo Map
Metadaten) {}
Dies bietet jedoch nur oberflächliche Unveränderlichkeit. Wenn die Karte extern geändert wird, ändert sich der interne Status des Datensatzes:
Karte
map = neue HashMap<>(); map.put('1' 'first');
Lesen einer CSV-Datei in Java
Student s = neuer Student('ABC' 101 Karte);
Java-Tostring
// Ändert den internen Status – NICHT sicher
map.put('2' 'second');
s.metadata().put('3' 'Third');
Notiz : Datensatz nur verwenden, wenn alle Felder unveränderliche Typen wie String int oder andere Datensätze sind.