Clonación de objetos en java

R3DKNIF3

Hola! a ver si alguno me podeís ayudar.

Por el proyecto que estoy haciendo me veo obligado a hacer varias clonaciones de objetos para poder hacer funciones como el controlz/i..

Ando un poco perdido sobre deep clone.

Que es necesario clonar aparte y que hace x defecto la interface Cloneable? (Strings, integers..)

Tengo varias Shape como podría clonarlas? / es necesario?

De momento hago esto:

    public Object clone() { 
        Object clone = null; 
        try { 
            clone = super.clone(); 
            } 
            catch(CloneNotSupportedException e)  {} 
             ((Enumeration)clone).setPointMap((HashMap<String, Point>)pointMap.clone());
             ((Enumeration)clone).setPointList((ArrayList<String>)pointList.clone());
             ((Enumeration)clone).setNoteMap((HashMap<String, NoteEnum>)noteMap.clone());
             ((Enumeration)clone).setShapeMap((HashMap<String, Shape>)shapeMap.clone());
            return clone; 
    } 

Pero claro, luego tengo que implementar la clonaciónen los objetos necesarios de los HashMap.

Alguien me puede aclarar un poco las ideas?¿

Muchas gracias!

LOc0

No contesta nadie...

A ver, una alternativa a clone para hacer copias profundas de objetos es la interfaz serializable y te evitas tener que implementar un método clone propio.

http://chuwiki.chuidiang.org/index.php?title=Serializaci%C3%B3n_de_objetos_en_java

La idea es convertir el objeto entero en un array de bytes y luego crear un objeto nuevo a partir de ese array de bytes.

Salu2 ;)

R3DKNIF3

si nadie contesta T_T.

Algo he leido sobre la serialización pero se supone que acarrea muchos mas recursos no? y hace que la aplicación sea mas lenta.

Lo quiero usar para un crtlz/i/c/v mirare a ver que tal va.

Muchas gracias!!

MTX_Anubis

pues es sencillo, simplemente tienes que clonar a mano las referencias a objetos que tengas en la propia clase y que todas las clase padres tengan bien definido el método.

Sin ponerte excepciones

public class A implements Cloneable {
  private B b = new B();

  public Object clone() {  //también puedes poner que devuelve A si quieres
    A o = (A) super.clone();
    if (b != null)
      o.b = (B) this.b.clone(); // si no la tiene definida entonces haces a mano la copia
    return o;
  }
}

A mí no me gusta usar el clone y de utilizarlo, lo haría en el mínimo de clases y que sean lo más simples posibles.

1
NeB1

en que casos es necesaria la interfaz clonable?

1 respuesta
MTX_Anubis

#5 Siempre que quieras utilizar el método clone()

La interfaz clonable no define ningún método sin embargo si una clase (o clases padre) no la implementa y se utiliza el método, se lanza una excepción.

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Cloneable.html
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#clone()

1 respuesta
NeB1

#6 jaja sí, eso me lo imaginaba, pero quería saber que utilidad tenía el método clone. Quería saber si era rollo el deepcopy de python o que...

1 respuesta
MTX_Anubis

#7 oh joe xD. Por defecto hace una copia superficial (basicamente copia el bloque de memoria en otro nuevo bloque), para hacer una profunda no queda más remedio que hacerla a mano xD

Y la utilidad, nusep xD. Yo sólo lo utilice en un tetris para clonar las piezas y comprobar los movimientos con ellas xD

JuAn4k4

Se supone que es para que al devolver una instancia de un objeto en un getter de una clase devuelvas un clone() de ella (por ejemplo fechas) para que al modificar dicho objeto no afecte a la clase que lo tiene.

Es decir, para la encapsulación.

public Class A {

private Date b  = Calendar.getInstance().getTime();

public Date getDate() {
return b; // mal..
}

public Date getDate2() {
 return b.clone(); // bien
}

}


public class B {
 private A a;

 public B() {
  a = new A();
  Date c = a.getDate(); // obtengo el objeto de dentro de A
  c.setTime(0); // he cambiado el  objeto a, sin llamar a metodos de la clase A ( y la encapsulación ?)
  Date d = a.getDate2(); // Me devuelve la fecha de A, pero no el objeto de A.
  d.setTime(242942); // NO afecta a A (encapsulación OK!) 
 }

Usuarios habituales

  • JuAn4k4
  • MTX_Anubis
  • NeB1
  • R3DKNIF3
  • LOc0