Tất cả các phương pháp để sao chép các đối tượng trong Java có sai sót nghiêm trọng:
Clone
- Các clone() phương pháp được bảo vệ, vì vậy bạn không thể gọi nó là trực tiếp trừ khi lớp trong ghi đè câu hỏi nó với một phương pháp công cộng.
- clone() không gọi hàm tạo. Bất kỳ nhà xây dựng nào. Nó sẽ cấp phát bộ nhớ, gán trường nội bộ
class
(mà bạn có thể đọc qua getClass()
) và sao chép các trường của tài liệu gốc.
Đối với vấn đề hơn với clone(), xem mục 11 của cuốn sách Joshua Bloch "Effective Java, Second Edition"
Serialize
Serialize thậm chí còn tồi tệ hơn; nó có nhiều lỗ hổng của clone()
và sau đó một số. Joshua có cả một chương với bốn mục cho chủ đề này một mình.
Giải pháp của tôi
Giải pháp của tôi là thêm một giao diện mới cho các dự án của tôi:
public interface Copyable<T> {
T copy();
T createForCopy();
void copyTo (T dest);
}
Mã này trông như thế này:
class Demo implements Copyable<Demo> {
public Demo copy() {
Demo copy = createForCopy();
copyTo (copy);
return copy;
}
public Demo createForCopy() {
return new Demo();
}
public void copyTo (Demo dest)
super.copyTo (dest);
...copy fields of Demo here...
}
}
Thật không may, tôi phải sao chép này mã cho tất cả các đối tượng của tôi nhưng nó luôn là cùng một mã, vì vậy tôi có thể sử dụng một mẫu trình soạn thảo Eclipse. Ưu điểm:
- Tôi có thể quyết định trình tạo nào cần gọi và cách khởi tạo trường nào.
- Khởi xảy ra theo một thứ tự xác định (lớp gốc đến lớp chẳng hạn)
- tôi có thể tái sử dụng đối tượng hiện có và ghi đè lên chúng
- Loại an toàn
- Singletons ở độc thân
Đối với các loại Java tiêu chuẩn (như bộ sưu tập, vv), tôi sử dụng một lớp tiện ích có thể sao chép chúng. Các phương thức có cờ và callbacks, vì vậy tôi có thể kiểm soát độ sâu của một bản sao.
Nguồn
2009-03-20 13:52:16
bản sao có thể có của [Làm thế nào để bạn tạo bản sao sâu của một đối tượng trong Java?] (Http://stackoverflow.com/questions/64036/how-do-you-make-a-deep-copy-of- an-object-in-java) –