Anasayfa > Java > Java – Object – Clone() Metodu

Java – Object – Clone() Metodu

Perşembe, 25 Kas 2010 Yorum ekle Yorumlara git

Java’da bütün sınıfların türediği Object sınıfının bir metodu olan clone() ile bir nesnenin kopyasını almak mümkün. Fakat pratikte bir takım sıkıntılar ile karşılaşılabiliyor. Bunun sebebi clone() metodunun primitive olmayan tipler için, nesnenin kopyasını almak yerine bu nesnenin referansını kopyalıyor olması. Buna “Shadow Copy” deniyor. Bu gibi durumlarda clone() metodunu ezip, nasıl bir kopyalama yapacağını belirlememiz gerekiyor. Sınıf tipi (Class Type) alanları da “gerçekten” kopyaladığımız bu tür kopyalamaya da “Deep Copy” deniyor.

Tabi kopyasını almak istediğimiz sınıfın “Cloneable” arayüzünü gerçeklemesi gerekiyor. Bu şekilde sınıf tanımında “implements Cloneable” şeklinde bir belirtim yapmazsak “CloneNotSupportedException” fırlatılıyor. Daha sonra bir “Deep Copy” gerekiyor ise, ki gerçekte muhtemelen gerekiyordur, clone() metodunu eziyoruz (override). Bu gibi “Deep Copy” yapmak istediğimiz durumlarda yapabileceğimiz iki şey var. Birincisi gerçek kopyasını almak istediğimiz sınıfın sınıf tipindeki alanlarini da “Cloneable” yapıp bahsi geçen clone() metodunda bu clone() metotlarını çağırıp, bu sınıf tipindeki alanlara atamak.

@Override
       public Object clone() {
		Employee e = null;
		try {
			e = (Employee) super.clone();
                        Department d = e.getDepartment().clone();
                        e.setDepartment(d);
		} catch (CloneNotSupportedException cnsex) {
			//TODO:catch this 
		}
		return e;
	}

İkincisi ise clone() metodunda gerçek nesneler oluşturarak bunları kopyalanmak istenen nesnenin sınıf tipindeki alanlara atamak.

@Override
	public Object clone() {
		Employee e = null;
		try {
			e = (Employee) super.clone();
                        e.setSalary(BigDecimal.ZERO);
		} catch (CloneNotSupportedException cnsex) {
			//TODO:catch this 
		}
		return e;
	}

Önemli bir diğer ilke de kopyalama sonucu oluşan kopya nesne ile kopyalanan asıl nesne için kopyaNesne != asılNesne ifadesinin, kopya işlemi sonrası ilk aşamada kopyaNesne.equals(asılNesne) ifadesinin ve kopyaNesne.getClass() != asılNesne.getClass() ifadesinin her zaman doğru değer döndürmesi gerektiğidir. Son olarak kopyalanmak istenen sınıfın List veya Set gibi Collection sınıfından türeyen alanları mevcutsa ve bunları da gerçekten kopyalamak istiyorsak, bu listelerin her bir elemanını tek tek kopyalamamız gerektiğini unutmamak gerekiyor.

Bu kadar yazdık ettik ama yine de Java gurusu abilerimiz nesne kopyalama işlemleri için clone() metoduna çok güvenmeyip ve bağlı kalmayıp bunun yerine istediğimiz şekilde kopyalamayı gerçekleştiren yapılandırıcı metotlar yazmamızı salık veriyorlar bize.

Güncelleme : Örnek koda ve kod yorumlarına şuradan bakılabilir. Umarım daha açıklayıcı olmuştur.

Ayrıca konu ile ilgili faydalı olduğunu düşündüğüm şuraya da bakmakta fayda var.

FacebooktwitterlinkedinmailFacebooktwitterlinkedinmail
Kategoriler:Java Etiketler:, , ,
  1. meh1
    Cumartesi, 18 Ara 2010 13:24 | #1

    s.a kardes iyi hoş anlatmayacalısmıssınız ama bu clone yaptıgınız sınıf hangi sınıf hangi neysneyi kopyaladınız sınıfınızın elemanları neler ? yani hangi sınıftan yeni clone ediyorsunuz bunu acıkca yazmadıgınız için acıkcası hiç birsey anlamadım acaba acıklamanız mümkün mü ?

  2. meh1
    Cumartesi, 18 Ara 2010 13:26 | #2

    hiç bilmeyen birine anlatır gibi acıklayabilirmisiniz ? pek kaynak bulamadıgım için ?

  3. Perşembe, 23 Ara 2010 01:34 | #3

    Müsait olduğum bir vakit güncelleyip, bir örnekle daha anlaşılır hale getirmeye çalışırım dostum

  4. Bora
    Pazartesi, 17 Oca 2011 11:21 | #4

    Teşekkürler

  5. Cumartesi, 23 Nis 2011 14:27 | #5

    Çok kuru olmus. Örnek yetersiz. Employee’nin bir üst class’i ne ? Super ile olusan objenin tipi ne ? Eger object ise
    bunu Epmloyee’e cast ettikten sonra “e” uzerinde getDepartment() nasil diyebiliyorsun ? “e” nin “Object” kisminin disindaki alanlar daha dolmadi.(Olustu ama dolmadi)
    getDepartment() diyemezsin.

    Kodu bir butun olarak vermen daha iyi olur.

    Employee e = null;
    e = (Employee) super.clone();
    Department d = e.getDepartment().clone();

  1. Henüz geri bağlantı yok