Câu trả lời ngắn gọn cho "tại sao không Cloneable
được tán thành?" (hoặc thực sự, tại sao không X
được phản đối, vì bất kỳ X
) là đã không có nhiều sự chú ý để phản đối họ.
Hầu hết những thứ bị phản đối gần đây đều bị phản đối vì có một kế hoạch cụ thể để loại bỏ chúng. Ví dụ, addPropertyChangeListener
và removePropertyChangeListener
các phương thức của LogManager không được dùng trong Java SE 8 với ý định loại bỏ chúng trong Java SE 9. (Lý do là chúng phụ thuộc lẫn nhau vào mô-đun phức tạp không cần thiết.) Thật vậy, các API này đã bị xóa khỏi quá trình phát triển JDK 9 ban đầu. xây dựng. (Lưu ý rằng các lệnh gọi người nghe thay đổi thuộc tính tương tự cũng bị xóa khỏi Pack200
; xem JDK-8029806 .)
Không có kế hoạch tương tự như vậy tồn tại cho Cloneable
và Object.clone()
.
Câu trả lời dài hơn sẽ liên quan đến việc thảo luận các câu hỏi tiếp theo, chẳng hạn như những gì người ta có thể mong đợi xảy ra với các API này, chi phí hoặc lợi ích nào sẽ tích lũy cho nền tảng nếu chúng không được chấp nhận và những gì được truyền đạt tới các nhà phát triển khi API bị từ chối. Tôi đã khám phá chủ đề này trong cuộc nói chuyện, Nợ và Khấu hao JavaOne gần đây của tôi . (Các slide có sẵn tại liên kết đó; video ở đây .) Hóa ra chính JDK đã không nhất quán trong việc sử dụng khấu hao. Nó được sử dụng để chỉ một số điều khác nhau, bao gồm cả, ví dụ,
Đây là nguy hiểm và bạn cần phải nhận thức những nguy cơ của việc sử dụng nó (ví dụ: Thread.stop()
, Thread.resume()
, và Thread.suspend()
).
Điều này sẽ được gỡ bỏ trong một bản phát hành trong tương lai
Điều này đã lỗi thời và bạn nên sử dụng một cái gì đó khác biệt (ví dụ: nhiều phương pháp trong java.util.Date
)
Tất cả đều là những ý nghĩa riêng biệt và các tập hợp con khác nhau của chúng áp dụng cho những thứ khác nhau không được dùng nữa. Và một số tập hợp con trong số chúng áp dụng cho những thứ không được dùng nữa (nhưng có lẽ không nên dùng nữa).
Cloneable
và Object.clone()
bị "phá vỡ" theo nghĩa là chúng có lỗi thiết kế và khó sử dụng chính xác. Tuy nhiên,clone()
vẫn là cách tốt nhất để sao chép mảng và nhân bản có một số hữu ích hạn chế để tạo các bản sao của các thể hiện của các lớp được thực hiện cẩn thận. Loại bỏ nhân bản sẽ là một thay đổi không tương thích sẽ phá vỡ rất nhiều thứ. Một hoạt động nhân bản có thể được thực hiện lại theo một cách khác, nhưng nó có thể sẽ chậm hơn Object.clone()
.
Tuy nhiên, đối với hầu hết mọi thứ, một nhà xây dựng sao chép thích hợp hơn để nhân bản. Vì vậy, có lẽ đánh dấuCloneable
là "lỗi thời" hoặc "thay thế" hoặc một cái gì đó tương tự sẽ là phù hợp. Điều này sẽ nói với các nhà phát triển rằng họ có thể muốn tìm ở nơi khác, nhưng nó sẽ không báo hiệu rằng cơ chế nhân bản có thể bị xóa trong một bản phát hành trong tương lai. Thật không may, không có điểm đánh dấu như vậy tồn tại.
Khi mọi thứ đứng vững, "sự phản đối" dường như ngụ ý loại bỏ cuối cùng - mặc dù thực tế là một số lượng nhỏ các tính năng bị phản đối đã bị loại bỏ - và vì vậy sự phản đối dường như không được bảo đảm cho cơ chế nhân bản. Có lẽ trong tương lai, một dấu hiệu thay thế có thể được áp dụng để hướng các nhà phát triển sử dụng các cơ chế thay thế.
CẬP NHẬT
Tôi đã thêm một số lịch sử bổ sung vào báo cáo lỗi . Frank Yellin, một người triển khai JVM sớm và là đồng tác giả của đặc tả JVM, đã đưa ra một số nhận xét để phản hồi lại nhận xét "bị mất trong thời gian" trong khuyến nghị TRC được trích dẫn trong câu trả lời khác . Tôi đã trích dẫn các phần có liên quan ở đây; thông báo đầy đủ là trong báo cáo lỗi.
Clonizable không có phương thức nào cho cùng một lý do mà serializable không có. Clonizable chỉ ra một thuộc tính của lớp, thay vì nói cụ thể bất cứ điều gì về các phương thức mà lớp hỗ trợ.
Trước khi phản ánh, chúng tôi cần một phương thức riêng để tạo một bản sao nông của Object. Do đó Object.clone () đã ra đời. Rõ ràng là nhiều lớp sẽ muốn ghi đè phương thức này và không phải lớp nào cũng muốn được sao chép. Do đó Clonizable được sinh ra để chỉ ra ý định của lập trình viên.
Vì vậy, trong ngắn hạn. Mục đích của Clonizable không phải là để chỉ ra rằng bạn có phương thức clone () công khai. Đó là để chỉ ra rằng bạn sẵn sàng được nhân bản bằng Object.clone () và tùy thuộc vào việc triển khai để quyết định có công khai clone () hay không.