Clonación de objetos

Tengo una clase EmpresaVO definida así (simplificada)
public class EmpresaVO implements Comparable, Serializable, Cloneable {
private int saldoTitulos = 0; // Saldo de títulos de la empresa
public EmpresaVO(int saldoTitulos) {
super();
this.saldoTitulos = saldoTitulos;
}
// Constructor que asegura la clonación profunda
private EmpresaVO(EmpresaVO toCopy) {
super();
this.saldoTitulos = new Integer(toCopy.getSaldoTitulos()).intValue();
}
public int getSaldoTitulos() {
return this.saldoTitulos;
}
public void setSaldoTitulos(int saldoTitulos) {
this.saldoTitulos = saldoTitulos;
}
public Object clone() {
return new EmpresaVO(this);
}
}

Y tengo una clase EmpresasConjunto definida así (simplificada)
// Clase que implementa el conjunto de empresas de un usuario
public class EmpresasConjunto implements Serializable, Cloneable {
private List empresas = null;
public EmpresasConjunto() {
super();
empresas = new LinkedList();
}
// Constructor que asegura la clonación profunda
private EmpresasConjunto(EmpresasConjunto toCopy) {
super();
this.empresas = new LinkedList(toCopy.getEmpresas());
}
public List getEmpresas() {
return this.empresas;
}
public void setEmpresas(List empresass) {
this.empresas = empresass;
}
// Añade una empresa al conjunto de empresas de un usuario
public boolean anadirEmpresa(EmpresaVO empr) {
if (!empresaExiste(empr)) {
empresas.add(empr);
return true;
}
return false;
}
// Devuelve, a partir de su nombre y de una cartera donde buscar, una empresa
public EmpresaVO obtenerEmpresa(String nombre, String idCart) {
for (int i = 0; i < empresas.size(); i++) {
EmpresaVO empr = (EmpresaVO) empresas.get(i);
if ( (empr.getIdCartera().equalsIgnoreCase(idCart)) &&
(empr.getNombre().equalsIgnoreCase(nombre)) )
return empr;
}
return null;
}
// Actualiza el saldo de títulos de una empresa tras una operación bursátil
public void actualizarSaldoTit(String empr, int numTit, String idCart) {
EmpresaVO empresa = obtenerEmpresa(empr, idCart);
int nuevSaldo = empresa.getSaldoTitulos() + numTit;
empresa.setSaldoTitulos(nuevSaldo);
}
public Object clone() {
return new EmpresasConjunto(this);
}
}

Cuanto activo un simulador guardo en sesión un objeto de la clase EmpresasConjunto para que cuando se desactive mantener las mismas empresas con su mismo saldo de títulos. Lo hago utilizando clone()
EmpresasConjunto empresasUsuario = (EmpresasConjunto) getEmpresasConjunto().clone();
session.setAttribute("estadoEmpresas", empresasUsuario);

Ahora se puede añadir empresas y/o modificar sus saldos de títulos mediante compra de títulos de esas empresas y cuando se desactive el simulador recupero lo almacenado en sesión, pero no sucede así.
Si el usuario introduce nuevas empresas en simulación, la copia en sesión no modifica, pero si compra títulos lo que implica incrementar el atributo de saldo de títulos, eso sí se altera en la copia en sesión.
El error lo tengo localizado, pero no sé a qué se debe ni cómo solucionarlo. Lo comento
Supongamos que estoy en simulación e inserto una compra. Primero se añade la empresa de la que se compran títulos (sólo si no existe, eso se verifica en el método)
getEmpresasConjunto().anadirEmpresa(empresa);

Si saco por salida estándar el contenido de la copia en sesión esta no se ve alterada. Hasta ahí bien. Procedo a actualizar el saldo de títulos de la empresa por la compra realizada
getEmpresasConjunto().actualizarSaldoTit(empr, numTit, idCart);

Saco nuevamente por salida estándar el contenido de la copia... Y en esta también se modifica el valor del atributo para el saldo de títulos! La "clave" puede estar en el método "actualizarSaldoTit()" especificado más arriba, pero no tengo ni idea de qué ni por qué

1 Respuesta

Respuesta
1
Creo que lo que pasa es que al hacer el clon de la lista de empresas, estas creando un clon no de la lista en sí, sino de la referencia a la lista, por lo que si la lista cambia, el "supuesto clon" cambia también. Para solucionar esto, lo que yo haría es, en el método clone() de EmpresasConjunto, crear una instancia nueva de EmpresasConjunto, y posteriormente, dentro de un bucle, hacer un clon de cada EmpresaVO y meterla en el clon de EmpresasConjunto. Algo así:
public class EmpresasConjunto implements Serializable, Cloneable {
......
......//Resto de código
......
public Object clone() {
   EmpresasConjunto clonEC = new EmpresasConjunto();
   EmpresaVO empresa, empresaClon;
    for (int i=0; i<empresas.size(); i++){
       empresa = (EmpresaVO)empresas.get(i);
       empresaClon = (EmpresaVO)empresa.clone();
       clonEC.anadirEmpresa(empresaClon);
  }
   return clonEC;
}
}
Como lo he editado aquí mismo no se si funciona, pero la idea creo que está clara. Espero que te haya servido. Un saludo y no olvides valorar mi respuesta ;-)
Carlos.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas