Copia profunda, superficial y perezosa con ejemplos de Java

En la programación orientada a objetos, la copia de objetos es crear una copia de un objeto existente, el objeto resultante se denomina copia de objeto o simplemente copia del objeto original. Hay varias formas de copiar un objeto, más comúnmente mediante un constructor de copia o clonación . .
Podemos definir la Clonación como “crear una copia del objeto”. La copia superficial, profunda y perezosa está relacionada con el proceso de clonación. 
Estas son en realidad tres formas de crear un objeto de copia.
Copia superficial 
 

  • Cada vez que usamos la implementación predeterminada del método de clonación, obtenemos una copia superficial del objeto, lo que significa que crea una nueva instancia y copia todo el campo del objeto en esa nueva instancia y lo devuelve como tipo de objeto, debemos convertirlo explícitamente en nuestro objeto original. Esta es una copia superficial del objeto.
  • El método clone() de la clase de objeto admite una copia superficial del objeto. Si el objeto contiene una variable de tipo primitivo y no primitivo o de referencia en una copia superficial, el objeto clonado también se refiere al mismo objeto al que se refiere el objeto original, ya que solo se copian las referencias del objeto y no los objetos referidos en sí.
  • Es por eso que el nombre de copia superficial o clonación superficial en Java. Si solo hay campos de tipo primitivo u objetos inmutables, entonces no hay diferencia entre la copia superficial y profunda en Java.

Java

//code illustrating shallow copy
public class Ex {
  
    private int[] data;
  
    // makes a shallow copy of values
    public Ex(int[] values) {
        data = values;
    }
  
    public void showData() {
        System.out.println( Arrays.toString(data) );
    }
}

El código anterior muestra una copia superficial. data simplemente se refiere a la misma array que vals.
 

Esto puede provocar efectos secundarios desagradables si los elementos de los valores se cambian a través de alguna otra referencia.
 

Java

public class UsesEx{
  
    public static void main(String[] args) {
        int[] vals = {3, 7, 9};
        Ex e = new Ex(vals);
        e.showData(); // prints out [3, 7, 9]
        vals[0] = 13;
        e.showData(); // prints out [13, 7, 9]
  
        // Very confusing, because we didn't
        // intentionally change anything about 
        // the object e refers to.
    }
}
Output 1 : [3, 7, 9]
Output 2 : [13, 7, 9]

Copia profunda 
 

  • Cada vez que necesitamos una copia propia para no usar la implementación predeterminada, lo llamamos copia profunda, cada vez que necesitamos una copia profunda del objeto que necesitamos implementar de acuerdo con nuestra necesidad.
  • Entonces, para una copia profunda, debemos asegurarnos de que todas las clases de miembros también implementen la interfaz Cloneable y anulen el método clone() de la clase de objeto.

Una copia profunda significa realmente crear una nueva array y copiar los valores.
 

Java

// Code explaining deep copy
public class Ex {
      
    private int[] data;
  
    // altered to make a deep copy of values
    public Ex(int[] values) {
        data = new int[values.length];
        for (int i = 0; i < data.length; i++) {
            data[i] = values[i];
        }
    }
  
    public void showData() {
        System.out.println(Arrays.toString(data));
    }
}

Java

public class UsesEx{
  
    public static void main(String[] args) {
        int[] vals = {3, 7, 9};
        Ex e = new Ex(vals);
        e.showData(); // prints out [3, 7, 9]
        vals[0] = 13;
        e.showData(); // prints out [3, 7, 9]
  
       // changes in array values will not be 
       // shown in data values. 
    }
}
Output 1 : [3, 7, 9]
Output 2 : [3, 7, 9]

Los cambios en los valores de la array no generarán cambios en los datos de la array.
cuándo usar qué 
No hay una regla estricta y rápida definida para seleccionar entre copia superficial y copia profunda, pero normalmente debemos tener en cuenta que si un objeto tiene solo campos primitivos, entonces obviamente debemos optar por una copia superficial, pero si el objeto tiene referencias a otros objetos, luego, según el requisito, se debe hacer una copia superficial o profunda. Si las referencias no están actualizadas, no tiene sentido iniciar una copia profunda.
Copia perezosa 
Una copia diferida se puede definir como una combinación de copia superficial y copia profunda. El mecanismo sigue un enfoque simple: en el estado inicial, se utiliza un enfoque de copia superficial. También se utiliza un contador para realizar un seguimiento de cuántos objetos comparten los datos. Cuando el programa quiere modificar el objeto original, comprueba si el objeto es compartido o no. Si se comparte el objeto, se inicia el mecanismo de copia profunda.
Resumen 
En la copia superficial, solo se copian los campos de tipo de datos primitivo mientras que las referencias a los objetos no se copian. La copia profunda implica la copia del tipo de datos primitivo, así como las referencias a objetos. No existe una regla estricta y rápida sobre cuándo hacer una copia superficial y cuándo hacer una copia profunda. Lazy copy es una combinación de ambos enfoques

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *