2011-06-17 13 views
9

que he entendido, el método clone() nos da la posibilidad de copiar objetos (sin refernce) en Java. Pero también leí, que la copia es superficial. Entonces, ¿qué sentido tiene? ¿Qué habilidad me da el método clone(), que una simple evaluación no ofrece?método clone() en Java

Respuesta

21

La diferencia es que puede modificar el objeto clonado sin modificar el objeto original.

Point p = new Point(1,2); 
Point p2 = p.clone(); 
Point p3 = p; 
p2.x = 5; 
p3.y = 7; 

El cambio en p3 no se alimentan de nuevo a p, mientras que el cambio en p2 no lo hace.

Vamos a ver cómo está la situación después de las declaraciones individuales (suponiendo 1, 2, 5, 7 serían objetos):

Point p = new Point(1,2); 

      .-----. .-----. 
p -----> | x -+--> | 1 | 
      |  | '-----' 
      |  | .-----. 
      | y -+--> | 2 | 
      '-----' '-----' 


Point p2 = p.clone(); 

      .-----. .-----. .-----. 
p -----> | x -+--> | 1 | <--+- x | <----- p2 
      |  | '-----' |  | 
      |  | .-----. |  | 
      | y -+--> | 2 | <--+- y | 
      '-----' '-----' '-----' 

Point p3 = p; 

      .-----. .-----. .-----. 
p -----> | x -+--> | 1 | <--+- x | <----- p2 
      |  | '-----' |  | 
      |  | .-----. |  | 
p3 -----> | y -+--> | 2 | <--+- y | 
      '-----' '-----' '-----' 


p2.x = 5; 

      .-----. .-----. .-----. .-----. 
p -----> | x -+--> | 1 | | x -+--> | 5 | 
      |  | '-----' |  | '-----' 
      |  | .-----. |  | 
p3 -----> | y -+--> | 2 | <--+- y | <----- p2 
      '-----' '-----' '-----' 


p3.y = 7; 

      .-----. .-----. .-----. .-----. 
p -----> | x -+--> | 1 | | x -+--> | 5 | 
      |  | '-----' |  | '-----' 
      |  | .-----. |  | 
p3 -----> | y | | 2 | <--+- y | <----- p2 
      '--+--' '-----' '-----' 
       |  .-----. 
       '---> | 7 | 
        '-----' 
+0

Gracias, pero no entiendo por qué p2.x no cambiará nada en p. Es correcto que tengamos 2 objetos difrentes, pero son puntos con la misma xey (porque la copia superficial). ¿Qué me estoy perdiendo? – Tom

+0

La asignación (en las últimas dos líneas) cambia a lo que apuntan 'x' y' y'. Incluso si '' p.x' y p2.x' tienen el mismo valor (en referencia al mismo objeto), que son variables diferentes, y asignar a uno no cambiar a la otra. (En este caso, ni siquiera son objetos, sino valores primitivos, pero lo mismo sería válido si fueran objetos). –

+0

En este ejemplo, no vemos la diferencia entre la clonación superficial y la profunda. –

4

Una asignación simple simplemente crear un alias para el objeto. Con clone(), cada miembro de atributo también se inicializará en el objeto clon. Sin embargo, si los miembros de Atributo tienen más objetos contenidos dentro de ellos, no se copiarán.

7

Una asignación copia la referencia de una instancia a una variable. A clon operación clonar el ejemplo (y asignar una referencia al clon).

Con asignación, que va a terminar con múltiples variables que apunta a una objeto, con la clonación tendrá múltiples variables que contienen referencias de múltiples objetos.

SomeCloneable a = new SomeCloneable(); 
SomeCloneable b = a;      // a and b point to the same object 

/* versus */ 

SomeCloneable a = new SomeCloneable(); 
SomeCloneable b = a.clone();    // a and b point to the different objects 
+0

'Cloneable' no hace que el' clon() 'pública método, sin embargo. Deberá declarar su 'a' y' b' como 'SomeCloneable'. –

+0

@ Paŭlo Ebermann - buena captura, gracias, lo corregiré! –

3

copia superficial es la predeterminado de objetos. puede anular el clon para hacer una copia profunda.

1

para clonar en profundidad lo que tiene que aplicar Cloneable y anular clone()

public class MyClass implements Cloneable { 

private Object attr = new Object(); 

@Override 
public Object clone() throws CloneNotSupportedException { 
    MyClass clone = (MyClass)super.clone(); 
    clone.attr = new Object(); 
    return clone; 
} 

@Override 
public String toString() { 
    return super.toString()+", attr=" + attr; 
} 

public static void main(String[] args) throws Exception { 
    MyClass x = new MyClass(); 
    System.out.println("X="+x); 
    MyClass y = (MyClass)x.clone(); 
    System.out.println("Y="+y); 
} 

}