Cloneable
trong Java vốn đã bị hỏng. Cụ thể, vấn đề lớn nhất của tôi với giao diện là nó mong đợi một hành vi của phương thức mà không định nghĩa chính phương thức đó. Vì vậy, nếu duyệt qua danh sách Cloneable
bạn phải sử dụng phản chiếu để truy cập hành vi được xác định của nó. Tuy nhiên, trong Java 8, bây giờ chúng ta có các phương thức mặc định và bây giờ tôi hỏi tại sao không có phương thức mặc định là clone()
trong Cloneable
.Tại sao không có bản sao mặc định() trong Cloneable trong Java 8
Tôi hiểu lý do tại sao interfaces cannot default Object methods, tuy nhiên, đây là một quyết định thiết kế rõ ràng và do đó có thể có ngoại lệ.
tôi loại hình dung ti Object.clone()
và thay đổi mã nội thất của nó để cái gì đó như:
if(this instanceof Cloneable) {
return ((Cloneable) this).clone();
}
else {
throw new CloneNotSupportedException();
}
Và di chuyển trên bất cứ điều gì kỳ diệu làm cho clone()
làm điều này như một phương pháp mặc định trong Cloneable
. Điều này không thực sự khắc phục rằng clone()
vẫn có thể dễ dàng được triển khai không chính xác, nhưng đó là một cuộc thảo luận khác của chính nó.
Theo như tôi vẫn có thể thay đổi này sẽ là hoàn toàn tương thích ngược:
- Lớp học hiện ghi đè
clone()
nhưng đã không thực hiệnCloneable
(TẠI SAO ?!) vẫn sẽ được kỹ thuật ổn (ngay cả khi chức năng không thể , nhưng điều này không khác gì trước đó). - Các lớp hiện đang ghi đè
clone()
, nhưng đã triển khaiCloneable
sẽ vẫn hoạt động tương tự khi triển khai. - Các lớp hiện không ghi đè
clone()
nhưng đã triển khaiCloneable
(TẠI SAO ?!) giờ đây sẽ tuân thủ đặc điểm kỹ thuật, ngay cả khi không phải là hoàn toàn chính xác. - Những người đã sử dụng phản ánh và được gọi là
Object.clone()
vẫn hoạt động bình thường. super.clone()
sẽ vẫn có chức năng giống nhau ngay cả khi nó tham chiếuObject.clone()
.
Chưa kể điều này sẽ giải quyết một vấn đề lớn mà Cloneable
là. Trong khi tẻ nhạt và vẫn dễ thực hiện không chính xác, nó sẽ giải quyết một vấn đề hướng đối tượng lớn với giao diện.
Vấn đề duy nhất tôi có thể thấy với điều này là những vấn đề triển khai Cloneable
không bắt buộc phải ghi đè clone()
, nhưng điều này không khác gì so với trước đây.
Điều này đã được thảo luận trong nội bộ, nhưng chưa bao giờ kết quả? Nếu vậy, tại sao? Nếu đó là lý do giao diện không thể mặc định đối tượng phương pháp, nó sẽ không có ý nghĩa để làm cho một ngoại lệ trong trường hợp này vì tất cả các đối tượng kế thừa Cloneable
đang mong đợi clone()
anyway?
Tôi nhớ đọc ở đâu đó (từ các nguồn chính thức) mà 'Cloneable' đã bị hỏng nên nó thậm chí còn không đáng để sửa chữa. Nhưng một trong những vấn đề với phương pháp mặc định của bạn là sử dụng 'this' là khó khăn ở đó. – Tunaki
Về cơ bản, những gì @Tunaki nói là chính xác. Sự trở lại-trên-phức tạp cho loại nhảy hoop này chỉ là không có; chúng tôi đã chọn đầu tư ngân sách {thời gian, nỗ lực, phức tạp} ở các khu vực khác mang lại nhiều giá trị hơn. –
Không có điểm nào trong việc tạo phương thức 'mặc định' như vậy. Nếu có một phương thức trong 'java.lang.Object' và phương thức' default' có cùng tên và chữ ký trong một 'giao diện', phương thức được khai báo trong' java.lang.Object' vẫn thắng cho các lời gọi không đủ tiêu chuẩn. Và nếu phương thức trong 'java.lang.Object' vẫn' bảo vệ', tất cả các triển khai 'Cloneable' được thực thi để redeclare phương thức là' public', trong khi thay đổi nó thành 'public' vẫn sẽ yêu cầu thích ứng với các hiện thực hiện có. Nói cách khác, kết quả không khác với việc định nghĩa phương thức 'abstract clone()' trong giao diện 'Cloneable'. – Holger