Tôi đã đọc trên thực hiện một bản sao sâu của một mảng chính xác, tuy nhiên tôi đã nhầm lẫn về cách thực hiện #clone()
. Nó là một thành viên của lớp java.lang.Object
, nhưng nếu bạn đọc javadocs:Tại sao #clone() không có trong giao diện Cloneable?
Thứ nhất, nếu lớp của đối tượng này không thực hiện giao diện Cloneable, sau đó một CloneNotSupportedException được ném.
Vậy tại sao xác định phương thức clone
ở nơi đầu tiên? Chắc chắn nếu một phương thức chỉ có thể được sử dụng khi một giao diện có mặt, bạn sẽ đặt phương thức đó vào giao diện. Giao diện Cloneable
trống; nó chỉ là một giao diện điểm đánh dấu được sử dụng bởi Java để đảm bảo rằng việc sử dụng phương thức clone
là hợp pháp.
Làm theo cách này cũng loại bỏ khả năng để làm cho việc sử dụng Generics để đảm bảo an toàn kiểu:
class Foo implements Cloneable { // Valid.
@Override
public Object clone() throws CloneNotSupportedException {
// ...
}
}
class TypeSafeFoo implements Cloneable<TypeSafeFoo> { // Not valid.
@Override
public TypeSafeFoo clone() throws CloneNotSupportedException {
// ...
}
}
Tại sao Java thực hiện nó theo cách này? Tôi chắc rằng họ có lý do chính đáng, nhưng tôi không thể hình dung ra được.
Trên thực tế đây là một lỗ hổng thiết kế như đã nói bởi Joshua Bloch –
Đây là một trong nhiều lý do nhân bản được coi là bị hỏng. –