ProgramlamaJava geliştiricisi

Java'da shallow copy ve deep copy arasındaki farkları açıklayın. Nasıl uygulanırlar ve ne zaman ihtiyaç duyulabilir?

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

Cevap

Shallow copy (yüzeysel kopyalama) yeni bir nesne oluşturur, ancak içsel nesnelere olan referansları kopyalar, nesneleri kendilerini değil. Deep copy (derin kopyalama) yeni bir nesne oluşturur ve orijinal nesneye gömülü tüm nesneleri rekürsif olarak kopyalar, böylece kopya ve orijinal arasında ortak referanslar yoktur.

Ne zaman kullanılmalı:

  • Eğer nesnenin yapısı değiştirilebilir içsel nesneleri içermiyorsa veya iç nesneleri değiştirmek gerekmiyorsa, shallow copy yeterlidir.
  • Eğer iç nesnelerin değişebilirliği kritikse ve kopya üzerindeki herhangi bir değişiklik orijinal nesneyi etkilememeliyse, deep copy gereklidir.

Uygulama örneği:

// İç nesne olan bir sınıf örneği class Address { String city; Address(String city) { this.city = city; } } class Person implements Cloneable { String name; Address address; Person(String name, Address address) { this.name = name; this.address = address; } // Shallow copy public Person clone() throws CloneNotSupportedException { return (Person) super.clone(); } // Deep copy public Person deepClone() { return new Person(this.name, new Address(this.address.city)); } }

Kandırmaca Sorusu

clone() metodu ile deep copy uygulanabilir mi?

Cevap: Hayır, standart Object.clone() metodu yalnızca "shallow copy" gerçekleştirir. Deep copy elde etmek için, ya tüm iç alanları elle kopyalamak gerekir ya da üçüncü taraf kütüphaneleri (örn. Apache Commons Lang) kullanmak gerekir.

Örnek:

@Override public Person clone() throws CloneNotSupportedException { Person cloned = (Person) super.clone(); cloned.address = new Address(this.address.city); // deep copy elle return cloned; }

Hikaye

Büyük bir CRM projesinde, nesnelerin kopyalanması super.clone() üzerinden uygulandıktan sonra, geliştirici kopyaların tam bağımsızlığını bekliyordu, ancak kopyalanan kullanıcının adresini değiştirirken, orijinal adres de değişti. Hata, yayın sonrası ortaya çıktı ve müşteri veritabanında karışıklığa neden oldu.


Hikaye

Derin kopyalama için standart Serializable mekanizması seçildi. Ancak iç nesnelerden birinin Serializable olarak bildirilmesi unutuldu, bu da çalışma sırasında hata (NotSerializableException) ve yedekleme sırasında veri kaybına neden oldu.


Hikaye

Bir mikro serviste, DTO'ları kopyalamak için BeanUtils.copyProperties kütüphanesi kullanıldı, ancak mekanizmanın yalnızca shallow copy uyguladığını fark etmediler. Yeniden yapılandırmadan sonra, iç koleksiyonlardaki değişikliklerin veritabanından alınan orijinal verilere etki ettiği birçok belirgin olmayan hata ortaya çıktı.