una - duplicar un objeto en java
Copie un objeto en Java (7)
Tengo un objeto que necesito copiar en Java. Necesito crear una copia y ejecutar algunas pruebas sin cambiar el objeto original.
Supuse que necesitaba usar el método clone (), pero esto está protegido. Después de haber hecho algunas investigaciones en la red, puedo ver que esto puede ser anulado con un método público en mi clase. Pero no puedo encontrar una explicación sobre cómo hacer esto. ¿Como se puede hacer esto?
Además, ¿es esta la mejor manera de lograr lo que necesito?
Hay dos enfoques populares. Una es proporcionar un método de clone
como usted mencionó, como tal.
public class C implements Cloneable {
@Override public C clone() {
try {
final C result = (C) super.clone();
// copy fields that need to be copied here!
return result;
} catch (final CloneNotSupportedException ex) {
throw new AssertionError();
}
}
Presta atención a los "campos de copia ... ¡aquí!" parte. El result
inicial es solo una copia superficial, lo que significa que si hay una referencia a un objeto, tanto el original como el result
compartirán el mismo objeto. Por ejemplo, si C
contiene datos private int[] data
es probable que desee copiar eso.
...
final C result = (C) super.clone();
result.data = data.clone();
return result;
...
Tenga en cuenta que no es necesario copiar los campos primitivos, ya que su contenido ya está copiado, o los objetos inmutables, ya que no pueden cambiar de todos modos.
El segundo enfoque es proporcionar un constructor de copia.
public class C {
public C(final C c) {
// initialize this with c
}
}
O una fábrica de copias.
public class C {
public static C newInstance(final C c) {
return new C(c);
}
private C(final C c) {
// initialize this with c
}
}
Ambos enfoques tienen sus respectivas propiedades. clone
es bueno porque es un método, por lo que no es necesario saber el tipo exacto. Al final, siempre debes terminar con una copia "perfecta". El constructor de copias es agradable porque la persona que llama tiene la oportunidad de decidir, como se puede ver en las Colecciones de Java.
final List c = ...
// Got c from somewhere else, could be anything.
// Maybe too slow for what we''re trying to do?
final List myC = new ArrayList(c);
// myC is an ArrayList, with known properties
Recomiendo elegir cualquiera de los enfoques, el que más te convenga.
Usaría los otros enfoques, como la copia reflectiva o la serialización / deserialización inmediata, solo en pruebas unitarias. Para mí, se sienten menos apropiados para el código de producción, principalmente por cuestiones de rendimiento.
Joshua Bloch tiene algunas cosas interesantes que decir sobre clonables . Dependiendo del tamaño / construcción del objeto, agregaría un constructor de copia al objeto, o serializar / deserializar usando una de las soluciones mencionadas anteriormente.
Para el código de prueba, la serialización es quizás la respuesta más segura, especialmente si el objeto ya es Serializable, pruebe Apache Commons SerializationUtils para una implementación.
Algunas opciones:
- Puede implementar
Cloneable
para su objeto y poner el métodoclone()
como público. Vea la explicación completa aquí: http://www.cafeaulait.org/course/week4/46.html
Sin embargo, esto produce una copia superficial y podría no ser algo que desee. - Puedes serializar y deserializar tu objeto. Tendrá que implementar una interfaz
Serializable
para el objeto y todos sus campos. - Puede usar
XStream
para realizar la serialización a través de XML; no tendrá que implementar nada aquí.
Otra opción al usar Copy Constructor (de Java Practices ):
public final class Galaxy {
public Galaxy (double aMass, String aName) {
fMass = aMass;
fName = aName;
}
/**
* Copy constructor.
*/
public Galaxy(Galaxy aGalaxy) {
this(aGalaxy.getMass(), aGalaxy.getName());
//no defensive copies are created here, since
//there are no mutable object fields (String is immutable)
}
/**
* Alternative style for a copy constructor, using a static newInstance
* method.
*/
public static Galaxy newInstance(Galaxy aGalaxy) {
return new Galaxy(aGalaxy.getMass(), aGalaxy.getName());
}
public double getMass() {
return fMass;
}
/**
* This is the only method which changes the state of a Galaxy
* object. If this method were removed, then a copy constructor
* would not be provided either, since immutable objects do not
* need a copy constructor.
*/
public void setMass( double aMass ){
fMass = aMass;
}
public String getName() {
return fName;
}
// PRIVATE /////
private double fMass;
private final String fName;
/**
* Test harness.
*/
public static void main (String... aArguments){
Galaxy m101 = new Galaxy(15.0, "M101");
Galaxy m101CopyOne = new Galaxy(m101);
m101CopyOne.setMass(25.0);
System.out.println("M101 mass: " + m101.getMass());
System.out.println("M101Copy mass: " + m101CopyOne.getMass());
Galaxy m101CopyTwo = Galaxy.newInstance(m101);
m101CopyTwo.setMass(35.0);
System.out.println("M101 mass: " + m101.getMass());
System.out.println("M101CopyTwo mass: " + m101CopyTwo.getMass());
}
}
Hay varias formas de copiar objetos en java (superficial o profunda).
Esta respuesta te ayudará.
Puede usar la clase org.apache.commons.lang3.SerializationUtils para la clonación de objetos, - Class debe implementar la interfaz Serializable.
- ClassName copyobject = SerializationUtils.clone (classobjectTocopy)
SerializationUtils.clone también es compatible con la instancia de Google App Engine