2009-07-01 13 views
15

Si tengo:La confusión acerca de la interfaz cloneable y Object.clone() en Java

class foo implements Cloneable 

y luego hacer:

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

puedo obtener una copia superficial sin necesidad de escribir ningún código bar.clone() como Normalmente tendría que hacer cuando implemente una interfaz.

Mi entendimiento es que las funciones de la interfaz deben ser rellenados por la clase que implementa, y Object.clone() no tiene ninguna aplicación (según los documentos, "la clase de objeto en sí no implementa la interfaz Cloneable")

Así ¿De dónde viene mi clon superficial? ¿Dónde está el código que implementa bar.clone() si Object.clone() no tiene implementación? Estoy confundido.

+0

Te animo a que aceptes una respuesta o pidas más aclaraciones para que podamos llegar a la respuesta correcta :-). – Tom

+0

@Tom algo seguro :) – ambertch

Respuesta

27

Be muy cuidadoso usando clonar. De hecho, lo evitaría por completo. Tengo nunca lo necesitaba. PERO ... Dicho esto, la mejor discusión sobre el tema que he leído es la de Joshua Bloch, en Java efectivo. Lea el Elemento 11: "Anule el clon juiciosamente".

HAGA POR FAVOR un favor y lea ese artículo. De hecho, recomiendo leer todo el capítulo (y el resto del libro). Todo lo que necesitas saber sobre el clon y por qué te advierto sobre él está ahí.

Espero que esto ayude.

+3

+1 para Java efectivo. La discusión sobre la clonación es excelente, como lo es todo el libro. –

+0

Esta debería ser casi la única respuesta. Teniendo en cuenta la excelente discusión de Joshua Bloch sobre los defectos de diseño inherentes a Cloneable, casi podríamos decir que para empezar es solo un error de diseño en Java. Casi siempre es mejor utilizar un constructor de copias/fábrica estática. –

+2

El enlace está "roto" :( –

6

Object.clone() tiene una implementación:

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

Este enlace explica la interfaz Cloneable: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Cloneable.html

un objeto debe implementar la interfaz Cloneable con el fin de llamar la clone() método, de lo contrario, arroja una CloneNotSupportedException.

Por definición, todas las clases en Java extienden la clase de objeto base, y la clase de objeto tiene un método clone() predeterminado, aunque el objeto en sí no implementa Cloneable. Se llamará al método clone() de la clase Object si no lo reemplaza usted mismo.

+0

ah, ya veo. Leí mal los documentos: el objeto tiene código para clonar(), simplemente no implementa clonable Entonces, ¿cuál es el mecanismo para aplicar la implementación clonable para llamar a class.clone()? ¿Es esto algo de lo que JRE es consciente para verificar deliberadamente? – ambertch

+0

La respuesta rápida - nada. La interfaz determina el comportamiento de la implementación del objeto clone(). Si una clase es clonable, Object.clone() devuelve una copia; de lo contrario, lanza CloneNotSupportedException. La interfaz clonable esencialmente modifica el comportamiento de la implementación de su superclase de clone(). – Cambium

1

Si tengo: "foo clase implementa cloneable"

y luego hacer: Barra = new foo(); bar.clone();

puedo obtener una copia superficial sin necesidad que escribir ningún código bar.clone() como hago normalmente tendría que hacer cuando implementar una interfaz.

Eso solo funcionaría si lo está llamando dentro de la clase "foo", porque el método .clone() heredado de Object está protegido.

Mi entendimiento es que las funciones de una interfaz debe ser llenado por en la clase que implementa, y Object.clone() no tiene aplicación (según los documentos, "el objeto de clase por sí mismo no implementar el interfaz Cloneable ")

(1) Object.clone() tiene una implementación. Hace una copia superficial del objeto si el objeto implementa Cloneable. (2) El método .clone() no es parte de ninguna interfaz. (3) Tener un método .clone() e implementar la interfaz Cloneable son cosas completamente independientes. Solo necesita implementar la interfaz Cloneable si tiene la intención de utilizar el método Objectclone; sin embargo, esta es la forma recomendada de escribir un método clone para su clase: obtener su copia del método clone de la superclase, que eventualmente pasa al método Objectclone.

+0

Gracias, sí, estás escribiendo, es malo ya que he leído mal la oración y he combinado "implementos conectables" con "tener una implementación" – ambertch

Cuestiones relacionadas