ProgrammierungJava-Entwickler

Was sind immutable Objekte in Java, was ist ihr Wert und wie implementiert man korrekt eine eigene immutable-Klasse?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

Immutable-Objekte sind Objekte, deren Zustand nach der Erzeugung nicht mehr geändert werden kann. Ihre Hauptmerkmale sind:

  • Alle Felder sind final;
  • Sie enthalten keine Setter;
  • Zu den Objekten innerhalb (z.B. Sammlungen) kann kein veränderlicher Verweis erhalten werden.

Vorteile von immutable-Objekten:

  • Sie sind sicher für den gleichzeitigen Zugriff (thread-sicher);
  • Sie lassen sich leicht cachen und wiederverwenden als Schlüssel in Sammlungen;
  • Sie vereinfachen das Debuggen und Testen;
  • Weniger Bugs aufgrund unerwarteter Zustandsänderungen.

Beispiel einer Implementierung einer immutable-Klasse:

public final class Person { private final String name; private final int age; private final List<String> phones; public Person(String name, int age, List<String> phones) { this.name = name; this.age = age; // Schutz vor Mutation der übergebenen Liste this.phones = Collections.unmodifiableList(new ArrayList<>(phones)); } public String getName() { return name; } public int getAge() { return age; } public List<String> getPhones() { return phones; } // Geben Sie eine read-only-Liste zurück }

Fangfrage.

Warum ist String in Java immutable und was würde passieren, wenn dem nicht so wäre? Viele antworten "zur Sicherheit", aber was bedeutet das in der Praxis?

Antwort:

String wird an vielen Stellen verwendet: als Schlüssel in Sammlungen, in der Sicherheitslogik (z.B. Passwörter). Wenn man eine Zeichenkette über einen Verweis ändern könnte, hätte dies Auswirkungen auf alle anderen Verweise auf dasselbe Objekt, was eine korrekte Funktionsweise von Sammlungen (z.B. HashMap - beim Berechnen von hashCode) unmöglich macht und zu Sicherheitsanfälligkeiten führen könnte.

Beispiele für reale Fehler aufgrund von Unkenntnis der Feinheiten des Themas.


Geschichte

In einem großen Bankprojekt wurden interne Sammlungen (eine Liste von Transaktionen) über einen normalen Getter übergeben. Dadurch konnte die Liste von außen verändert werden, was die Invarianten verletzte (z.B. das Hinzufügen einer Transaktion mit einem falschen Datum). Dies führte zu Datenverlust, bis Collections.unmodifiableList zurückgegeben wurde.

Geschichte

In der Stammklasse der Konfiguration wurden ungeschützte Objektfelder (Date, List) aufbewahrt. In einem Thread wurde die Konfiguration geändert, während im anderen veraltete oder inkonsistente Daten abgerufen wurden, was dazu führte, dass der Geschäftsalgorithmus nicht korrekt arbeitete.

Geschichte

Im Anmeldesystem wurden Passwörter in einem veränderlichen Objekt aufbewahrt. Durch unsicheren Zugriff wurde plötzlich das Passwort eines anderen Benutzers "geleakt", da dasselbe Objekt von mehreren Threads verwendet wurde.