เมธอด clone() ใช้สร้างสำเนาของออบเจ็กต์ของคลาสที่ implement Cloneable interface โดยค่า default จะทำ field-by-field copy เนื่องจาก Object class ไม่มีข้อมูลเกี่ยวกับ members ของคลาสเฉพาะที่ออบเจ็กต์เรียกเมธอดนี้ ดังนั้น หากคลาสมีแค่ primitive data type members จะสร้างสำเนาใหม่ของออบเจ็กต์และคืน reference ไปยังสำเนาใหม่ แต่ถ้าคลาสมี members ที่เป็น class type จะคัดลอกแค่ object references ของ members นั้น ทำให้ member references ในออบเจ็กต์ต้นฉบับและ cloned object ชี้ไปยังออบเจ็กต์เดียวกัน
จะได้ CloneNotSupportedException หากพยายามเรียก clone() บนออบเจ็กต์ของคลาสที่ไม่ implement Cloneable interface ซึ่งเป็น marker interface การ implement interface นี้เพียงแค่บ่งชี้ว่า Object.clone() สามารถเรียกใช้ได้บนออบเจ็กต์ของ implementing class
Syntax
protected Object clone() throws CloneNotSupportedException
เราสามารถ implement clone() ได้ 2 แบบ
Shallow Copy
เป็นผลลัพธ์จาก default cloning functionality ของ Object.clone() หากคลาสมี non-primitive data type members ในกรณี Shallow Copy cloned object ก็จะชี้ไปยังออบเจ็กต์เดียวกับที่ออบเจ็กต์ต้นฉบับชี้ไป เนื่องจากคัดลอกแค่ object references ไม่ได้คัดลอก referred objects
ตัวอย่าง Shallow Copy
public class ShallowCopyTest {
public static void main(String args[]) {
A a1 = new A();
A a2 = (A) a1.clone();
a1.sb.append("Tutorialspoint!");
System.out.println(a1);
System.out.println(a2);
}
}
class A implements Cloneable {
public StringBuffer sb = new StringBuffer("Welcome to ");
public String toString() {
return sb.toString();
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
}
Output
Welcome to Tutorialspoint! Welcome to Tutorialspoint!
Deep Copy
เราต้อง override เมธอด clone() สำหรับคลาสที่มี non-primitive type members เพื่อให้ได้ Deep Copy เนื่องจากต้องการให้ member objects ถูก clone ด้วย ซึ่ง default cloning mechanism ไม่ทำให้
ตัวอย่าง Deep Copy
public class DeepCopyTest {
public static void main(String args[]) {
A a1 = new A();
A a2 = (A) a1.clone();
a1.sb.append(" TutorialsPoint!");
System.out.println(a1);
System.out.println(a2);
}
}
class A implements Cloneable {
public StringBuffer sb = new StringBuffer("Welcome to ");
public String toString() {
return sb.toString();
}
public Object clone() {
try {
A a = (A) super.clone();
a.sb = new StringBuffer(sb.toString());
return a;
} catch (CloneNotSupportedException e) {
}
return null;
}
}
Output
Welcome to TutorialsPoint! Welcome to