Phương thức clone và giao diện Cloneable - 1

"Chào, Amigo!"

"Chào Kim."

"Tôi sẽ nói với bạn về phương thức clone()."

"Mục đích của phương pháp này là sao chép một đối tượng, hay nói cách khác, để tạo một bản sao/bản sao/nhân bản của đối tượng."

"Khi phương thức này được gọi, máy ảo Java sẽ tạo và trả về một bản sao của đối tượng mà nó được gọi.

Việc triển khai phương thức sao chép của lớp Đối tượng rất nguyên thủy: chỉ một đối tượng mới được tạo và các giá trị của các trường của đối tượng ban đầu được gán cho các trường của nó.

Nếu đối tượng được sao chép chứa các tham chiếu đến các đối tượng khác, thì các tham chiếu đó sẽ được sao chép. Bản sao của các đối tượng đó sẽ không được tạo."

"Hmm. Đó không phải là nhiều để tiếp tục."

"Vấn đề là, máy ảo Java không biết đối tượng nào có thể hoặc không thể được sao chép. Ví dụ: các tệp không thể được sao chép. Điều này cũng đúng đối với luồng System.in."

"Vì vậy, câu hỏi về nhân bản chính thức đã được đặt ra cho các nhà phát triển của một lớp." Điều này hoàn toàn tương tự như cách xử lý phương thức bằng. Thậm chí còn có một thứ có thể so sánh với hashCode: giao diện Cloneable."

" Giao diện Cloneable được gọi là 'giao diện đánh dấu': nó không có bất kỳ phương thức nào và được sử dụng để đánh dấu các lớp nhất định.

"Nếu nhà phát triển của một lớp tin rằng các đối tượng của lớp có thể được nhân bản, anh ta sẽ đánh dấu nó bằng giao diện này (nghĩa là làm cho lớp đó thực hiện Cloneable)."

"Nếu nhà phát triển không thích cách triển khai tiêu chuẩn của phương thức sao chép, anh ta phải viết cách riêng của mình để tạo đối tượng trùng lặp theo đúng cách."

"Khi bạn gọi phương thức clone (), Java sẽ kiểm tra xem đối tượng có hỗ trợ giao diện Cloneable hay không. Nếu có, thì nó sẽ sao chép đối tượng bằng cách sử dụng phương thức clone (); nếu không, nó sẽ ném một CloneNotSupportedException."

"Nói cách khác, chúng ta phải ghi đè phương thức nhân bản hoặc làm cho lớp thực hiện Cloneable?"

"Có, nhưng bạn vẫn phải ghi đè phương thức. Phương thức clone() được khai báo là được bảo vệ, vì vậy nó chỉ có thể được gọi bởi các lớp trong gói của nó (java.lang.*) hoặc các lớp con của chúng."

"Tôi hơi bối rối—vậy tôi cần làm gì để sao chép một đối tượng?"

"Nếu bạn muốn sử dụng phương thức nhân bản «mặc định» của lớp Đối tượng, bạn cần phải:

" a) Thêm giao diện Cloneable vào lớp học của bạn"

" b) Ghi đè phương thức sao chép và gọi phần triển khai của siêu lớp trong phần triển khai của bạn:"

class Point implements Cloneable
{
 int x;
 int y;

 public Object clone()
 {
  return super.clone();
 }
    }

"Hoặc bạn có thể tự mình viết triển khai phương thức sao chép hoàn toàn:"

class Point
{
 int x;
 int y;

 public Object clone()
 {
  Point point = new Point();
  point.x = this.x;
  point.y = this.y;
  return point;
 }
}

"Đó là một phương pháp thú vị. Tôi chắc chắn rằng tôi sẽ sử dụng nó. Thỉnh thoảng..."