ProgrammatieJava ontwikkelaar

Leg het verschil uit tussen shallow copy en deep copy van objecten in Java. Hoe kunnen ze worden geïmplementeerd, en in welke situaties is het belangrijk om dit verschil te begrijpen?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

In Java is shallow copy (oppervlakkige kopie) het kopiëren van een object waarbij alleen de verwijzingen naar genestelde objecten worden gekopieerd, en niet de objecten zelf. Wijzigingen in de genestelde objecten zullen dus ook in de kopie en in het origineel worden weerspiegeld. Deep copy (diepe kopie) houdt in dat er nieuwe onafhankelijke kopieën van alle genestelde objecten worden gemaakt.

Voorbeeld van shallow copy (via 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(); } } // Gebruik Person p1 = new Person("Ivan", new Address("Moscow")); Person p2 = (Person) p1.clone(); p2.address.city = "Petersburg"; System.out.println(p1.address.city); // Zal "Petersburg" afdrukken — oppervlakkige kopie

Voorbeeld van 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; } }

Diepe kopie maakt het mogelijk om een volledig onafhankelijke kopie van het object te maken.

Vraag met een valstrik.

Vraag: Kan de methode clone() worden gebruikt voor gegarandeerde diepe kopieën van willekeurige complexe objecten?

Antwoord: Nee, de standaard clone() maakt alleen een oppervlakkige kopie (shallow copy). Voor diepe kopieën is het nodig om clone() in alle geneste klassen te overschrijven en expliciet alle verwijzingsvelden te klonen. Ook ondersteunen veel collecties en standaard klassen geen diepe kloning.

Voorbeelden van echte fouten door onwetendheid van de subtiliteiten van het onderwerp.


Verhaal

Een collectie gebruikers en hun adressen werd gekloond met de methode clone() zonder diepe kopie. Na het wijzigen van het adres van een gebruiker, veranderde het adres van de andere ook omdat de verwijzing werd gekopieerd. Gegevens in de database "lekten" tussen gebruikers.


Verhaal

Bij het serialiseren van een complex object met geneste collecties werd clone() gebruikt in plaats van een diepe kopie. Na herstel uit serialisatie bleken de gegevens inconsistent en traden er NPE's op.


Verhaal

In de REST API werden DTO-objecten standaard gekloond via BeanUtils.copyProperties(), wat leidde tot het delen van dezelfde collectie tussen klanten. Als gevolg hiervan kon de gebruiker andermans gegevens zien en bewerken.