2009-07-01 54 views
15

Nếu tôi có:Lẫn lộn về giao diện cloneable và Object.clone() trong java

class foo implements Cloneable 

và sau đó làm:

bar = new foo(); 
bar.clone(); 

tôi nhận được một bản sao cạn mà không cần phải viết bất kỳ mã bar.clone() như Tôi thường sẽ cần phải làm gì khi tôi thực hiện một giao diện.

sự hiểu biết của tôi là chức năng của một giao diện phải được điền vào bởi lớp thực hiện nó, và Object.clone() không có người thực hiện (theo các tài liệu, "Các đối tượng lớp không tự thực hiện các giao diện Cloneable")

Vì vậy, nơi bản sao nông của tôi đến từ đâu? Mã nào triển khai bar.clone() nếu Object.clone() không triển khai? Tôi bối rối.

+0

Tôi khuyến khích bạn chấp nhận câu trả lời hoặc yêu cầu làm rõ thêm để chúng tôi có thể nhận được câu trả lời đúng :-). – Tom

+0

@Tom chắc chắn điều :) – ambertch

Trả lời

27

Be rất cẩn thận sử dụng bản sao. Trong thực tế, tôi sẽ tránh nó hoàn toàn. Tôi có không bao giờ cần. NHƯNG ... mà đang được nói, thảo luận tốt nhất về chủ đề mà tôi từng đọc là Joshua Bloch, trong Java hiệu quả. Đọc mục 11: "Ghi đè bản sao một cách khôn ngoan".

XIN VUI LÒNG VUI LÒNG VUI LÒNG VUI LÒNG VUI LÒNG VUI LÒNG VUI LÒNG Làm ơn cho bạn và đọc mục đó. Tôi thực sự khuyên bạn nên đọc toàn bộ chương đó (và phần còn lại của cuốn sách). Tất cả mọi thứ bạn cần biết về bản sao và lý do tại sao tôi cảnh báo bạn về nó là ở đó.

Hy vọng điều này sẽ hữu ích.

+3

+1 cho Java hiệu quả. Các cuộc thảo luận về nhân bản là tuyệt vời, như là toàn bộ cuốn sách. –

+0

Điều này gần như là câu trả lời duy nhất. Với sự thảo luận tuyệt vời của Joshua Bloch về các lỗi thiết kế vốn có trong Cloneable, người ta gần như có thể nói rằng đó chỉ là một lỗi thiết kế trong Java để bắt đầu. Bạn gần như luôn luôn tốt hơn bằng cách sử dụng một nhà xây dựng bản sao/nhà máy tĩnh. –

+2

Liên kết bị "hỏng": ( –

6

Object.clone() có một thực hiện:

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#clone()

liên kết này giải thích giao diện Cloneable: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Cloneable.html

Một đối tượng phải thực hiện các giao diện Cloneable để gọi clone() nếu không, nó sẽ ném ra một CloneNotSupportedException. Theo định nghĩa, tất cả các lớp trong Java mở rộng lớp Object cơ sở, và lớp Object có một phương thức clone() mặc định, mặc dù Object không thực hiện Cloneable. Phương thức clone() của lớp Object sẽ được gọi nếu bạn không tự ghi đè lên nó.

+0

ah tôi nhìn thấy. Tôi hiểu sai tài liệu - đối tượng DOES có mã cho clone(), nó không thực hiện cloneable Vậy thì cơ chế thực thi việc thực thi cloneeable là gì để gọi class.clone()? Đây có phải là điều gì đó mà JRE biết là cố ý kiểm tra không? – ambertch

+0

Câu trả lời nhanh - không có gì. Giao diện dtermines hành vi của bản sao Object() thực hiện. Nếu một lớp là Cloneable, Object.clone() trả về một bản sao, nếu không nó sẽ ném CloneNotSupportedException. Giao diện Cloneable cơ bản sửa đổi hành vi của việc triển khai bản sao của siêu lớp(). – Cambium

1

Nếu tôi có: "class foo thực hiện cloneable"

và sau đó làm: thanh = new foo(); bar.clone();

Tôi nhận được bản sao nông mà không cần để viết bất kỳ mã bar.clone() nào như I thường cần phải làm khi tôi triển khai giao diện.

Điều đó sẽ chỉ hoạt động nếu bạn gọi nó trong lớp "foo", vì phương thức .clone() được kế thừa từ Object được bảo vệ.

sự hiểu biết của tôi là chức năng một giao diện phải được điền trong bởi lớp thực hiện nó, và Object.clone() không có người thực hiện (theo các tài liệu, "Lớp Object không tự triển khai giao diện Cloneable ")

(1) Object.clone() không thực hiện. Nó làm cho một bản sao nông của đối tượng nếu đối tượng thực hiện Cloneable. (2) Phương pháp .clone() không phải là một phần của bất kỳ giao diện nào. (3) Có phương pháp .clone() và triển khai giao diện Cloneable là những điều hoàn toàn riêng biệt. Bạn chỉ cần triển khai giao diện Cloneable nếu bạn định sử dụng phương thức Object 'clone; tuy nhiên, đây là cách được khuyến nghị để viết phương thức clone cho lớp của bạn - để lấy bản sao của nó từ phương thức clone của siêu lớp, cuối cùng là phương thức 'clone.

+0

Cảm ơn, có bạn đang viết - xấu của tôi khi tôi đọc sai câu và xúi giục "thực hiện coneable" với "đang triển khai" – ambertch