Más información sobre la copia profunda y la copia superficial de java

Sabemos que copiar es generar un nuevo objeto exactamente igual que el objeto original, pero copiar también se divide en formas y grados. Echemos un vistazo a qué es copia superficial y qué es copia profunda

Copia superficial

En Java, el método clone () de la clase java.lang.Object se utiliza para la clonación (copia superficial, los puntos de atributo son los mismos).
Este método crea una copia de un objeto, lo llama a través de la asignación de campo por campo y devuelve una referencia al objeto.
Para lograr una copia superficial, debe implementar la interfaz Cloneable. No hay ningún método en la interfaz, y apunta al clone () de la clase java.lang.Object.

protected native Object clone() throws CloneNotSupportedException;

Es un método nativo, implementado por C / C ++.
Veamos el ejemplo para comprender por qué se llama copia superficial.
Primero, hay una clase de objeto de diccionario, que implementa la interfaz de clonación

@Data
class Dictionary implements Cloneable {
    
    

   private String name;

   private List<String> words;

   @Override
   public Object clone() {
    
    
       try {
    
    
           return super.clone();
       } catch (CloneNotSupportedException e) {
    
    
           e.printStackTrace();
       }
       return null;
   }
}

public static void shallowCopy() {
    
    
       Dictionary dictionary1 = new Dictionary();
       dictionary1.setName("汉语词典");
       dictionary1.setWords(new ArrayList<String>() {
    
    {
    
    
           add("你好");
           add("浅拷贝");
       }});
       Dictionary dictionary2 = (Dictionary) dictionary1.clone();
       System.out.println(dictionary1 == dictionary2);
       dictionary2.getWords().add("新词语");
       System.out.println("dictionary1: " + dictionary1.toString());
       System.out.println("dictionary2: " + dictionary2.toString());

       dictionary1.setName("新名字");
       System.out.println("dictionary1: " + dictionary1.toString());
       System.out.println("dictionary2: " + dictionary2.toString());
   }

resultado de la operación:

false
dictionary1: Dictionary(name=汉语词典, words=[你好, 浅拷贝, 新词语])
dictionary2: Dictionary(name=汉语词典, words=[你好, 浅拷贝, 新词语])
dictionary1: Dictionary(name=新名字, words=[你好, 浅拷贝, 新词语])
dictionary2: Dictionary(name=汉语词典, words=[你好, 浅拷贝, 新词语])

Por el resultado, sabemos que dictionary1 y dictionary2 no apuntan al mismo objeto, de hecho se crean dos objetos, pero cuando se modifican las propiedades del segundo objeto, el primer objeto también cambia.
Para verificar la copia superficial que mencionamos anteriormente, las propiedades de los dos objetos apuntan al mismo objeto en el montón.

Copia profunda

En comparación con la copia superficial, la copia profunda significa que los atributos también son objetos nuevos.También podemos implementar la interfaz clonable para cada atributo del objeto para lograr el efecto de copia profunda. También podemos usar la serialización y deserialización para lograr una copia profunda.
Primero implemente la interfaz serializable para Diccionario

@Data
class Dictionary implements Cloneable, Serializable {
    
    

    private String name;

    private List<String> words;

    @Override
    public Object clone() {
    
    
        try {
    
    
            return super.clone();
        } catch (CloneNotSupportedException e) {
    
    
            e.printStackTrace();
        }
        return null;
    }
}
private static void deepCopy() throws IOException, ClassNotFoundException {
    
    
        Dictionary dictionary1 = new Dictionary();
        dictionary1.setName("汉语词典");
        dictionary1.setWords(new ArrayList<String>() {
    
    {
    
    
            add("你好");
            add("浅拷贝");
        }});

        Dictionary dictionary2 = null;

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(dictionary1);

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream);
        dictionary2 = (Dictionary) ois.readObject();

        // 测试方法没关闭流 实际项目记得关闭流
        System.out.println(dictionary1 == dictionary2);
        dictionary2.getWords().add("新词语");
        System.out.println("dictionary1: " + dictionary1.toString());
        System.out.println("dictionary2: " + dictionary2.toString());
    }

resultado de la operación

false
dictionary1: Dictionary(name=汉语词典, words=[你好, 深拷贝])
dictionary2: Dictionary(name=汉语词典, words=[你好, 深拷贝, 新词语])

Puedo ver que tanto el objeto como sus propiedades son independientes. Esta es una copia profunda.

Supongo que te gusta

Origin blog.csdn.net/sc9018181134/article/details/104054171
Recomendado
Clasificación