Phương thức clone() được dùng để tạo bản sao của một đối tượng của lớp triển khai giao diện Cloneable. Theo mặc định, nó thực hiện sao chép theo trường (field-by-field copy) vì lớp Object không có ý tưởng về các thành viên của lớp cụ thể mà đối tượng gọi phương thức này. Vì vậy, nếu lớp chỉ có các thành viên kiểu dữ liệu nguyên thủy thì một bản sao mới của đối tượng sẽ được tạo và tham chiếu đến bản sao mới sẽ được trả về. Nhưng nếu lớp chứa các thành viên kiểu lớp thì chỉ có tham chiếu đối tượng đến các thành viên đó được sao chép, do đó tham chiếu thành viên trong cả đối tượng gốc và đối tượng sao chép đều tham chiếu đến cùng một đối tượng.
Chúng ta sẽ nhận được CloneNotSupportedException nếu cố gắng gọi phương thức clone() trên đối tượng của lớp không triển khai giao diện Cloneable. Giao diện này là giao diện đánh dấu (marker interface) và việc triển khai giao diện này đơn giản chỉ cho biết phương thức Object.clone() có thể được gọi trên các đối tượng của lớp triển khai.
Cú pháp
protected Object clone() throws CloneNotSupportedException
Chúng ta có thể triển khai phương thức clone() theo hai cách:
Sao chép nông (Shallow Copy)
Đây là kết quả của chức năng sao chép mặc định do Object.clone() cung cấp nếu lớp có các thành viên kiểu dữ liệu không nguyên thủy. Trong trường hợp Sao chép nông, đối tượng sao chép cũng tham chiếu đến cùng một đối tượng mà đối tượng gốc tham chiếu vì chỉ có tham chiếu đối tượng được sao chép chứ không phải các đối tượng được tham chiếu.
Ví dụ
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;
}
}
Kết quả
Welcome to Tutorialspoint! Welcome to Tutorialspoint!
Sao chép sâu (Deep Copy)
Chúng ta cần ghi đè phương thức clone() cho các lớp có thành viên kiểu không nguyên thủy để đạt được Sao chép sâu vì nó yêu cầu các đối tượng thành viên cũng phải được sao chép, điều mà cơ chế sao chép mặc định không làm.
Ví dụ
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;
}
}
Kết quả
Welcome to TutorialsPoint! Welcome to