Considere el siguiente código:
DummyBean dum = new DummyBean();
dum.setDummy("foo");
System.out.println(dum.getDummy()); // prints 'foo'
DummyBean dumtwo = dum;
System.out.println(dumtwo.getDummy()); // prints 'foo'
dum.setDummy("bar");
System.out.println(dumtwo.getDummy()); // prints 'bar' but it should print 'foo'
Por lo tanto, quiero copiar el dumque dumtwoy el cambio dumsin afectar al dumtwo. Pero el código anterior no está haciendo eso. Cuando cambio algo dum, dumtwotambién está ocurriendo el mismo cambio .
Supongo que, cuando digo dumtwo = dum, Java copia solo la referencia . Entonces, ¿hay alguna forma de crear una copia nueva dumy asignarla dumtwo?

Básico: Copia de objetos en Java.
Supongamos que un objeto

obj1, que contiene dos objetos, contieneObj1 y contenidoObj2 .copia superficial: la copia

superficial crea una nueva
instanceclase de la misma clase y copia todos los campos a la nueva instancia y la devuelve. La clase de objeto proporciona unclonemétodo y proporciona soporte para la copia superficial.Copia profunda : una copia profunda ocurre cuando un objeto se copia junto con los objetos a los que se refiere . La imagen a continuación se muestra
obj1después de que se haya realizado una copia profunda. No solo seobj1ha copiado , sino que también se han copiado los objetos que contiene. Podemos usarJava Object Serializationpara hacer una copia profunda. Desafortunadamente, este enfoque también tiene algunos problemas ( ejemplos detallados ).Posibles problemas:
clonees difícil de implementar correctamente.Es mejor usar copias defensivas , constructores de copias (como @egaga reply) o métodos estáticos de fábrica .
clone()método público , pero no conoce el tipo de objeto en tiempo de compilación, entonces tiene un problema. Java tiene una interfaz llamadaCloneable. En la práctica, debemos implementar esta interfaz si queremos hacer un objetoCloneable.Object.cloneestá protegido , por lo que debemos anularlo con un método público para que sea accesible.clone()método de todas las variables de objeto miembro también hace una copia profunda, esto es demasiado arriesgado de suponer. Debe controlar el código en todas las clases.Por ejemplo, org.apache.commons.lang.SerializationUtils tendrá un método para clonar en profundidad usando la serialización ( Fuente ). Si necesitamos clonar Bean, entonces hay un par de métodos de utilidad en org.apache.commons.beanutils ( Fuente ).
cloneBeanclonará un bean en función de los captadores y establecedores de propiedades disponibles, incluso si la clase de bean no implementa Cloneable.copyPropertiescopiará los valores de propiedad del bean de origen al bean de destino para todos los casos en que los nombres de propiedad sean los mismos.fuente
En el paquete
import org.apache.commons.lang.SerializationUtils;hay un método:Ejemplo:
fuente
SerializableSolo sigue lo siguiente:
y donde quiera obtener otro objeto, simplemente realice la clonación. p.ej:
fuente
¿Por qué no hay una respuesta para usar Reflection API?
Es muy simple
EDITAR: Incluir objeto hijo a través de recursión
fuente
Class A { B child; } Class B{ A parent; }class car { car car = new car(); }Utilizo la biblioteca JSON de Google para serializarla y luego crear una nueva instancia del objeto serializado. Hace una copia profunda con algunas restricciones:
no puede haber referencias recursivas
no copiará matrices de tipos dispares
las matrices y las listas deben escribirse o no encontrará la clase para instanciar
es posible que necesite encapsular cadenas en una clase que declare
También uso esta clase para guardar las preferencias del usuario, las ventanas y otras cosas que se deben volver a cargar en tiempo de ejecución. Es muy fácil de usar y efectivo.
fuente
Sí, solo estás haciendo referencia al objeto. Puede clonar el objeto si implementa
Cloneable.Mira este artículo wiki sobre cómo copiar objetos.
Consulte aquí: copia de objetos
fuente
Agrega
Cloneabley debajo del código a tu claseUtilizar este
clonedObject = (YourClass) yourClassObject.clone();fuente
Si. Necesita copiar en profundidad su objeto.
fuente
Esto tambien funciona. Asumiendo modelo
Primero agregue
compile 'com.google.code.gson:gson:2.8.1'a su aplicación> gradle & sync. EntoncesPuede excluir el uso de un campo utilizando la
transientpalabra clave después del modificador de acceso.Nota: esta es una mala práctica. Tampoco recomiendo usar
CloneableoJavaSerializationes lento y roto. Escriba el constructor de copias para obtener el mejor rendimiento ref .Algo como
Estadísticas de prueba de iteración 90000: la
línea
UserAccount clone = gson.fromJson(gson.toJson(aO), UserAccount.class);tarda 808 msLa línea
UserAccount clone = new UserAccount(aO);tarda menos de 1 msConclusión: usa gson si tu jefe está loco y prefieres la velocidad. Use el segundo constructor de copias si prefiere la calidad.
También puede usar el complemento generador de código de constructor de copia en Android Studio.
fuente
Aquí hay una explicación decente de
clone()si terminas necesitándolo ...Aquí: clonar (método Java)
fuente
Use una utilidad de clonación profunda:
Esto copiará en profundidad cualquier objeto Java, échale un vistazo en https://github.com/kostaskougios/cloning
fuente
Deep Cloning es su respuesta, que requiere implementar la
Cloneableinterfaz y anular elclone()método.Lo llamarás así
DummyBean dumtwo = dum.clone();fuente
dummy, aString, es inmutable, no necesita copiarloPara hacer eso tienes que clonar el objeto de alguna manera. Aunque Java tiene un mecanismo de clonación, no lo use si no es necesario. Cree un método de copia que haga la copia por usted y luego haga:
Aquí hay más consejos sobre diferentes técnicas para realizar una copia.
fuente
Además de copiar explícitamente, otro enfoque es hacer que el objeto sea inmutable (ningún
setmétodo mutante u otro). De esta manera, la pregunta nunca surge. La inmutabilidad se vuelve más difícil con objetos más grandes, pero ese otro lado de eso es que te empuja en la dirección de dividirte en pequeños objetos coherentes y compuestos.fuente
Alternativa al método de copia del constructor de egaga . Probablemente ya tenga un POJO, así que simplemente agregue otro método
copy()que devuelva una copia del objeto inicializado.Si ya tiene una
DummyBeany quiere una copia:Pero ambos funcionan bien, en última instancia depende de usted ...
fuente
fuente
Puede copiar en profundidad automáticamente con XStream, desde http://x-stream.github.io/ :
Agréguelo a su proyecto (si usa maven)
Entonces
Con esto, tiene una copia sin la necesidad de implementar ninguna interfaz de clonación.
fuente
java.beans.XMLEncoderuna API Java estándar que también serialice a XML (aunque no precisamente para propósitos de copia profunda).y en tu código:
fuente
Pase el objeto que desea copiar y obtenga el objeto que desea:
Ahora analiza el
objDestobjeto deseado.¡Feliz codificación!
fuente
Puede intentar implementar
Cloneabley usar elclone()método; sin embargo, si usa el método de clonación, debería, por norma, SIEMPRE anularObjectelpublic Object clone()método.fuente
Si puede agregar una anotación al archivo fuente, se puede usar un procesador de anotación o un generador de código como este .
Se
DummyBeanBuildersgenerará una clase , que tiene un método estáticodummyBeanUpdaterpara crear copias superficiales, de la misma manera que lo haría manualmente.fuente
Úselo
gsonpara duplicar un objeto.Supongamos que tengo un objeto
person.fuente