ProgramlamaJava Geliştirici

Java'da shallow copy ile deep copy nesneleri arasındaki farkı açıklayın. Bunlar nasıl uygulanabilir ve bu farkı anlamanın önemli olduğu durumlar nelerdir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Java'da shallow copy (yüzeysel kopyalama), nesnenin yalnızca iç içe nesnelere olan referanslarının kopyalandığı, nesnelerin kendilerinin değil. Bu nedenle, iç içe nesnelerdeki değişiklikler hem kopyada hem de orijinalinde yansıyacaktır. Deep copy (derin kopyalama) tüm iç nesnelerin yeni bağımsız kopyalarının oluşturulmasını ifade eder.

Shallow copy örneği (clone ile)

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(); } } // Kullanım Person p1 = new Person("Ivan", new Address("Moscow")); Person p2 = (Person) p1.clone(); p2.address.city = "Petersburg"; System.out.println(p1.address.city); // "Petersburg" yazdırır — yüzeysel kopyalama

Deep copy örneği

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

Derin kopyalama, nesnenin tamamen bağımsız bir kopyasını oluşturmayı sağlar.

Zor bir soru.

Soru: Herhangi bir karmaşık nesnenin garantili derin kopyasını elde etmek için clone() metodunu kullanabilir miyiz?

Cevap: Hayır, standart clone() yalnızca yüzeysel kopyalama yapar (shallow copy). Derin kopyalamak için, iç içe tüm sınıflarda clone() metodunu geçersiz kılmak ve tüm referans alanlarını açıkça klonlamak gerekir. Ayrıca birçok koleksiyon ve standart sınıf derin kopyalamayı desteklememektedir.

Konuyla ilgili bilinçsizlikten kaynaklanan gerçek hata örnekleri.


Hikaye

Bir kullanıcılar ve onların adresleri koleksiyonu, derin kopyalama olmadan clone() metodu ile kopyalandı. Bir kullanıcının adresi değiştirildiğinde, diğerinin adresi de değişti çünkü referans kopyalanıyordu. Veriler arasında "sızma" oldu.


Hikaye

İç içe koleksiyonlarla karmaşık bir nesnenin serileştirilmesi sırasında, deep copy yerine clone() kullanıldı. Serileştirmeden geri yüklemeyle veriler tutarsız hale geldi ve NPE oluştu.


Hikaye

REST API'de DTO nesneleri varsayılan olarak BeanUtils.copyProperties() ile kopyalandı, bu da bir koleksiyonun istemciler arasında paylaşılmasına neden oldu. Sonuç olarak, kullanıcı başkalarının verilerini görebiliyor ve düzenleyebiliyordu.