ProgrammierungJava-Entwickler

Erklären Sie den Unterschied zwischen shallow copy und deep copy von Objekten in Java. Wie kann man sie implementieren und in welchen Situationen ist es wichtig, diesen Unterschied zu verstehen?

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

Antwort.

In Java ist shallow copy (flaches Kopieren) eine Kopie eines Objekts, bei der nur die Referenzen auf die enthaltenen Objekte kopiert werden, nicht die Objekte selbst. Änderungen an den enthaltenen Objekten spiegeln sich sowohl in der Kopie als auch im Original wider. Deep copy (tiefes Kopieren) bedeutet, dass neue unabhängige Kopien aller enthaltenen Objekte erstellt werden.

Beispiel für shallow copy (über clone)

class Address implements Cloneable { String city; Address(String city) { this.city = city; } protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class Person implements Cloneable { String name; Address address; Person(String name, Address address) { this.name = name; this.address = address; } protected Object clone() throws CloneNotSupportedException { return super.clone(); } } // Verwendung Person p1 = new Person("Ivan", new Address("Moscow")); Person p2 = (Person) p1.clone(); p2.address.city = "Petersburg"; System.out.println(p1.address.city); // Gibt "Petersburg" aus - flaches Kopieren

Beispiel für deep copy

class Address implements Cloneable { String city; Address(String city) { this.city = city; } protected Object clone() throws CloneNotSupportedException { return new Address(this.city); } } class Person implements Cloneable { String name; Address address; Person(String name, Address address) { this.name = name; this.address = address; } protected Object clone() throws CloneNotSupportedException { Person cloned = (Person) super.clone(); cloned.address = (Address) address.clone(); return cloned; } }

Das tiefe Kopieren ermöglicht es, eine vollständig unabhängige Kopie eines Objekts zu erstellen.

Fangfrage.

Frage: Kann die Methode clone() für eine garantierte tiefe Kopie eines beliebigen komplexen Objekts verwendet werden?

Antwort: Nein, die Standardmethoden clone() machen nur flaches Kopieren (shallow copy). Für ein tiefes Kopieren muss clone() in allen enthaltenen Klassen überschrieben und alle Referenzfelder explizit geklont werden. Außerdem unterstützen viele Sammlungen und Standardklassen kein tiefes Klonen.

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


Geschichte

Die Sammlung von Benutzern und deren Adressen wurde mit der Methode clone() ohne tiefes Kopieren geklont. Nach der Änderung der Adresse eines Benutzers änderte sich die Adresse eines anderen, weil die Referenz kopiert wurde. Die Daten in der Datenbank "flossen" zwischen den Benutzern.


Geschichte

Beim Serialisieren eines komplexen Objekts mit enthaltenen Sammlungen wurde clone() anstelle einer tiefen Kopie verwendet. Nach der Wiederherstellung aus der Serialisierung waren die Daten inkonsistent und es gab NPEs.


Geschichte

In der REST API wurden DTO-Objekte standardmäßig über BeanUtils.copyProperties() geklont, was zu einer Teilung derselben Sammlung zwischen den Clients führte. Infolgedessen konnte ein Benutzer die Daten anderer sehen und bearbeiten.