Clone () vs Copy constructor, que se recomienda en Java

clonar método vs copiar constructor en java. cuál es la solución correcta. dónde usar cada caso?

El clon está roto, así que no lo uses.

EL METODO CLONE de la clase Object es un método algo mágico que hace lo que ningún método Java puro podría hacer: produce una copia idéntica de su objeto. Ha estado presente en la superclase Objeto primordial desde los días de lanzamiento Beta del comstackdor Java *; y, como toda magia antigua, requiere el conjuro apropiado para evitar que el hechizo falle inesperadamente

Prefiere un método que copie el objeto

 Foo copyFoo (Foo foo){ Foo f = new Foo(); //for all properties in FOo f.set(foo.get()); return f; } 

Leer más http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx

Tenga en cuenta que clone() no funciona de la caja. Deberá implementar Cloneable y anular el método clone() en public .

Hay algunas alternativas, que son preferibles (dado que el método clone() tiene muchos problemas de diseño, como se indica en otras respuestas), y el constructor de copias requerirá trabajo manual:

  • BeanUtils.cloneBean(original) crea un clon superficial, como el creado por Object.clone() . (esta clase es de commons-beanutils )

  • SerializationUtils.clone(original) crea un clon profundo. (es decir, el gráfico de propiedades completas está clonado, no solo el primer nivel) (de commons-lang ), pero todas las clases deben implementar Serializable

  • Java Deep Cloning Library ofrece clonación profunda sin la necesidad de implementar Serializable

clone () fue diseñado con varios errores (ver esta pregunta ), así que es mejor evitarlo.

De Effective Java 2nd Edition , Item 11: Anular el clon juiciosamente

Dado todos los problemas asociados con Cloneable, es seguro decir que otras interfaces no deberían extenderlo, y que las clases diseñadas para la herencia (Ítem 17) no deberían implementarlo. Debido a sus muchas deficiencias, algunos progtwigdores expertos simplemente eligen nunca anular el método de clonación y nunca invocarlo, excepto, tal vez, para copiar matrices. Si diseña una clase para la herencia, tenga en cuenta que si elige no proporcionar un método de clonación protegido con buen comportamiento, será imposible que las subclases implementen Clonación.

Este libro también describe las muchas ventajas que los constructores de copia tienen sobre Cloneable / clone.

  • No se basan en un mecanismo extralingüístico de creación de objetos propenso a riesgos
  • No exigen una adhesión inaplicable a las convenciones finamente documentadas
  • No entran en conflicto con el uso adecuado de los campos finales
  • No lanzan excepciones marcadas innecesarias
  • No requieren moldes.

Todas las colecciones estándar tienen constructores de copias. Usalos, usalos a ellos.

 List original = // some list List copy = new ArrayList(original); 

Tenga en cuenta que el constructor de copia limita el tipo de clase al del constructor de copia. Considera el ejemplo:

 // Need to clone person, which is type Person Person clone = new Person(person); 

Esto no funciona si la person puede ser una subclase de Person (o si la Person es una interfaz). Este es el punto principal de la clonación, es que puede clonar el tipo apropiado dinámicamente en el tiempo de ejecución (suponiendo que el clon esté implementado correctamente).

 Person clone = (Person)person.clone(); 

o

 Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer 

Ahora la person puede ser cualquier tipo de Person suponiendo que el clone se implementa correctamente.

Consulte también: ¿Cómo anular correctamente el método de clonación? . La clonación está rota en Java, es muy difícil hacerlo bien, e incluso cuando lo hace no ofrece mucho , por lo que realmente no vale la pena la molestia.

Gran tristeza: ni Cloneable / clone ni un constructor son excelentes soluciones: ¡NO QUIERO CONOCER LA CLASE DE IMPLEMENTACIÓN! (por ejemplo, tengo un mapa, que quiero copiar, usando la misma implementación oculta de MumbleMap) Solo quiero hacer una copia, si es compatible. Pero, por desgracia, Cloneable no tiene el método de clonación, por lo que no hay nada a lo que pueda escribir de forma segura para invocar clone ().

Sea cual sea la mejor biblioteca de “objetos copiados”, Oracle debería convertirlo en un componente estándar de la próxima versión de Java (a menos que ya lo esté, oculto en algún lugar).

Por supuesto, si más de la biblioteca (por ejemplo, Colecciones) fuera inmutable, esta tarea de “copia” desaparecería. Pero luego comenzamos a diseñar progtwigs Java con cosas como “invariantes de clase” en lugar de verdammt “patrón de frijol” (hacer un objeto roto y mutar hasta que sea bueno [suficiente]).