ProgramlamaJava Geliştirici

Java'da nesnelerin kopyalanması nedir, clone() yöntemiyle klonlama ile yapıcı aracılığıyla kopyalama arasındaki fark nedir ve hangi durumlarda hangi yöntemi kullanmalıyız?

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

Cevap.

Java'da nesnelerin kopyalanması, mevcut bir örneğin durumu ile aynı duruma sahip yeni bir nesne oluşturma sürecidir. Tarihsel olarak kopyalama, Java'nın ilk gelişim dönemlerinde nesneleri manuel olarak yeniden oluşturmadan kopyalama ihtiyacı doğduğunda önemli hale gelmiştir. Java, nesnelerin kopyalanması için evrensel bir yöntem sunmaz, bunun yerine clone() sözleşmesini ve kopyalayıcı yapıcı desenini kullanır.

Sorunun Tarihi

clone() yöntemi, nesnelerin klonlanması için standart bir mekanizma sağlamak amacıyla Cloneable arayüzüne entegre edilmiştir, ancak uygulanması birçok nüansa sahiptir ve genellikle hataların ortaya çıkmasına neden olur.

Problem

Ana sorun, "kutu içinde" gerçek bir derin kopyalamanın olmaması ve yüzeysel klonlama (shallow copy) sırasında öngörülemeyen davranışların ortaya çıkma olasılığıdır. Kopyalayıcı yapıcı, hem yüzeysel hem de derin kopyalamayı gerçekleştirmeye izin verir, ancak açık bir uygulama gerektirir.

Çözüm

Karmaşık nesnelerin güvenli ve doğru bir şekilde kopyalanması için, kopyalayıcı yapıcıyı veya fabrika yöntemini kullanmak daha tercih edilirken, clone() yalnızca nesne gerçekten bu sözleşmeye uyuyorsa dikkatli bir şekilde kullanılmalıdır.

Kod örneği:

// clone() ile yüzeysel klonlama public class Address implements Cloneable { String city; public Address(String city) { this.city = city; } @Override public Address clone() throws CloneNotSupportedException { return (Address) super.clone(); } } public class Person implements Cloneable { String name; Address address; public Person(String name, Address address) { this.name = name; this.address = address; } @Override public Person clone() throws CloneNotSupportedException { Person copy = (Person) super.clone(); copy.address = address.clone(); // address'in derin kopyası return copy; } } // Kopyalayıcı yapıcı public class Person { String name; Address address; public Person(Person other) { this.name = other.name; this.address = new Address(other.address.city); } }

Anahtar özellikler:

  • clone() arayüzünün Cloneable uygulanmasını ve clone yönteminin geçersiz kılınmasını gerektirir.
  • Yüzeysel kopyalama yalnızca referansları kopyalar, nesneleri değil.
  • Kopyalayıcı yapıcı, kopyalama derinliği ve istisna işleme üzerinde tam kontrol sağlar.

Tuzak Sorular.

Soru 1: Eğer sınıf Cloneable’ı uygulamıyorsa, clone() çağrıldığında ne olur?

clone(), nesne Cloneable arayüzünü uygulamıyorsa CloneNotSupportedException fırlatır.

Soru 2: clone() ile klonlama varsayılan olarak derin midir?

Hayır, varsayılan olarak yalnızca yüzeysel klonlama uygulanır, tüm referanslar olduğu gibi kopyalanır.

Soru 3: Derin klonlama için kopyalayıcı yapıcı olmadan ne yapabilirim?

Hayır, süreci kontrol etmek istiyorsanız, iç nesnelerin kopyalanmasını ya yapıcıda ya da clone() içinde elle yazmanız gerekir.

Yaygın Hatalar ve Anti-Desenler

  • Değiştirilebilir referans alanlarına sahip nesneler için yüzeysel klonlama kullanmak
  • clone sözleşmesini ihlal etmek (super.clone() çağrılmadan)
  • İstisna işleme eksikliği ve Cloneable uygulamadan klonlama olanağının olmaması

Gerçek Hayattan Bir Örnek

Olumsuz Durum

Geliştirici, List<Product> alanına sahip Order sınıfında standart clone() kullanmıştır. Sonuç olarak, kopyadaki ürünler listesi değiştiğinde, orijinaldeki ürünler de değişmiş ve bu bir hataya yol açmıştır.

Artılar:

  • Minimum kod.
  • Basit nesneler için hızlı klonlama.

Eksiler:

  • Değiştirilebilir alanlara sahip nesneleri kopyalarken ciddi hatalar.
  • Klonlama süreci üzerinde kontrol kaybı.

Olumlu Durum

Şirket, tüm alan varlıkları için kopyalayıcı yapıcıyı gerçekleştirmiş ve karmaşık iç içe nesnelerin klonlama sürecini testlerle desteklemiştir.

Artılar:

  • Kopyalama üzerinde tam kontrol.
  • Beklenmedik yan etkilerin olmaması.

Eksiler:

  • Daha fazla kod kapasitesi.
  • Sınıf yapısı değiştiğinde yapıcının desteklenmesi gerekliliği.