Giriş
Cloneable arayüzü kullanılması tavsiye edilmeyen bir arayüz. Deprecate edilmediği halde, deprecate edilmiş gibi kabul edilmesi isteniyor. Metodun imzası şöyle
1. Clone Metodu Constructor'ı Çağırmaz
clone metodu native çağrılarla direkt JVM heap içinde yeni bir nesne yaratır. Constructor'ımı çağırmak zorunda değildir.
clone metodu nesnenin her bir alanını yeni nesnenin alanına atar. Eğer alan reference type ise shallow copy oluşur. Eğer alan primitive tip veya Immutable ise sorun teşkil etmez.
3. CloneNotSupportedException
Object.clone() metodu eğer nesne Cloneable arayüzünden kalıtmamışsa bu exception'ı atar. Bu işi yapan metod Object sınıfında ve imzası şöyle
Cloneable arayüzü kullanılması tavsiye edilmeyen bir arayüz. Deprecate edilmediği halde, deprecate edilmiş gibi kabul edilmesi isteniyor. Metodun imzası şöyle
protected Object clone() throws CloneNotSupportedException
Bazı Özellikleri1. Clone Metodu Constructor'ı Çağırmaz
clone metodu native çağrılarla direkt JVM heap içinde yeni bir nesne yaratır. Constructor'ımı çağırmak zorunda değildir.
Animal animal = new Animal(101); //Constructor is executed.
Animal clone=(Animal)animal.clone() //Constructor is not executed. Why ?
2. Shallow Copy Yaratırclone metodu nesnenin her bir alanını yeni nesnenin alanına atar. Eğer alan reference type ise shallow copy oluşur. Eğer alan primitive tip veya Immutable ise sorun teşkil etmez.
3. CloneNotSupportedException
Object.clone() metodu eğer nesne Cloneable arayüzünden kalıtmamışsa bu exception'ı atar. Bu işi yapan metod Object sınıfında ve imzası şöyle
protected Object clone() throws CloneNotSupportedException
En Basit Nasıl Kodlarım
Cloneable arayüzünden kalıtır ve clone metodundan ata sınıfı çağırırım. Aslında metodumun ismi clone olmak zorunda değil, çünkü aslında Object.clone () metodunu override etmiyoruz. Amaç sadece Object.clone() metodunu çağırabilmek çünkü Object.clone() normalde protected olduğu için çağrılamaz. Açıklaması şöylesuper.clone() will call it's super.clone() and the chain will continue until the call reaches the clone() method of the Object class, which will create a field by field mem copy of our object and return it back.Örnek
Şöyle yaparız. Burada shallow copy oluşturulur. Metodumuz CloneNotSupportedException fırlattığı için beni çağıran kişinin bunu yakalaması gerekir.
public class Foo implements Cloneable {
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Örnek
Eğer tüm kod benim kontrolümdeyse ve CloneNotSupportedException fırlatılmayacağımdan eminsem şöyle yaparız. Böylece metod imzasındaki throws CloneNotSupportedException kısmından kurtulurum
public Course clone() {
Course c = null;
try {
c = (Course)super.clone();
} catch (CloneNotSupportedException e) {} // Won't happen
return c;
}
Örnek - Covariant Return Type
Örnek
Kopyalamak istediğimiz sınıfın bir tane final alanı olsun. Açıklaması şöyle.
We can not manipulate final fields in Object.clone() because final fields can only be changed through constructors.Bu sefer copy constructor yöntemini kullanırız. Şöyle yaparız.
public class Person implements Cloneable {
private final Brain brain; // brain is final since I do not want
// any transplant on it once created!
private int age;
public Person(Brain aBrain, int theAge) {
brain = aBrain;
age = theAge;
}
protected Person(Person another) {
Brain refBrain = null;
try {
refBrain = (Brain) another.brain.clone();
// You can set the brain in the constructor
} catch(CloneNotSupportedException e) {}
brain = refBrain;
age = another.age;
}
public Object clone() {
return new Person(this);
}
...
}
Kullanım Örnekleri
Basit bir dizi kopyalama örneği
Apache Commons ile
- BeanUtils.cloneBean(object)
- SerializationUtils (object)
verilen nesneyi serialize edip tekrar okuyarak klonlama imkanı sunuyor.
Basit bir dizi kopyalama örneği
byte[] a = {1,2,3};
byte[] b = (byte[]) a.clone();
System.out.print(a==b); //false verir
Diğer seçenekler ne olabilir ?Apache Commons ile
- BeanUtils.cloneBean(object)
- SerializationUtils (object)
verilen nesneyi serialize edip tekrar okuyarak klonlama imkanı sunuyor.
Ayrıca eğer nesne Fluent Interface şeklindeyse bazı metodlar da kopyasını döndürüyor. "Java Method Naming Convention" şöyle
Prefix Method Type Useof static factory Creates an instance where the factory is primarily validating the input parameters, not converting them.from static factory Converts the input parameters to an instance of the target class, which may involve losing information from the input.parse static factory Parses the input string to produce an instance of the target class.format instance Uses the specified formatter to format the values in the temporal object to produce a string.get instance Returns a part of the state of the target object.is instance Queries the state of the target object.with instance Returns a copy of the target object with one element changed; this is the immutable equivalent to a set method on a JavaBean.plus instance Returns a copy of the target object with an amount of time added.minus instance Returns a copy of the target object with an amount of time subtracted.to instance Converts this object to another type.at instance Combines this object with another.
with(), plus(), minus() gibi metodlar kopya dönebilir.
Örnek
Şöyle yaparızz
kitchen.order(pizzaFactory.getPizza(“crusty”).withToping(“x”).withGarlic());
Hiç yorum yok:
Yorum Gönder