¿Qué es copia superficial y copia profunda?

Los métodos para crear objetos Java incluyen nuevo, reflexión, deserialización y copia. Entonces, ¿qué es copiar? ¿Cuál es la diferencia entre copia superficial y copia profunda?

que es copiar

Copiar es reutilizar parte o la totalidad de los datos del objeto original y crear un nuevo objeto copiando sobre la base del objeto original.

Hay un método de clonación de tipo nativo en la clase Object

protected native Object clone() throws CloneNotSupportedException;

Si se puede copiar un objeto, la clase correspondiente al objeto debe implementar la interfaz Cloneable y anular el método de clonación de Object.

La interfaz Cloneable debe implementarse; de ​​lo contrario, llamar al método clon generará una excepción java.lang.CloneNotSupportedExecption

//Cloneable接口中没有任何参数或抽象方法,该接口只是一个标识
public interface Cloneable {
}
//如Student类,实现Cloneable接口,重写Object的clone方法
public class Student implements Cloneable{

    private String sname;

    private Integer sage;
    
    ...
    
    @Override
    protected Student clone() throws CloneNotSupportedException {
        return (Student) super.clone();
    }
}

tomar una castaña

public class cloneObject {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student = new Student("学生1",18);
        System.out.println("clone前的Student对象为:"+student);
        Student cloneStudent = student.clone();
        System.out.println("clone后的Student对象为:"+cloneStudent);
        System.out.println("Student对象与cloneStudent对象是否相等:"+student.equals(cloneStudent));
    }
}

El resultado de la impresión es

clone前的Student对象为:Student{sname='学生1', sage=18}
clone后的Student对象为:Student{sname='学生1', sage=18}
Student对象与cloneStudent对象是否相等:false

image.png Se puede ver que copiar crea un nuevo objeto.

¿Qué es una copia superficial?

Cambiaré la clase Student un poco más tarde para ilustrar

Además de los atributos de tipo String y tipo Integer en la clase Student, se agrega un atributo de tipo Teacher.Solo hay un atributo tname de tipo String en la clase Teacher.

public class Student implements Cloneable{

    private String sname;

    private Integer sage;

    private Teacher teacher;
    
    ...
    
    @Override
    protected Student clone() throws CloneNotSupportedException {
        return (Student) super.clone();
    }
public class Teacher {

    private String tname;

Vuelva a llamar al método de clonación del objeto alumno.

public static void main(String[] args) throws CloneNotSupportedException {
    Teacher teacher = new Teacher("罗翔老师");
    Student student = new Student("学生1",18,teacher);
    System.out.println("clone前的Student对象为:"+student);
    Student cloneStudent = student.clone();
    System.out.println("clone后的Student对象为:"+cloneStudent);
    System.out.println("Student对象与cloneStudent对象是否相等:"+student.equals(cloneStudent));
    System.out.println("student对象和cloneStudent对象中的teacher属性是否相等:"+student.getTeacher().equals(cloneStudent.getTeacher()));
}

Se espera que el resultado de la comparación de los dos objetos de estudio sea falso. Sin embargo, el resultado de la comparación de la propiedad del maestro en los dos objetos de estudiante es verdadero.

clone前的Student对象为:Student{sname='学生1', sage=18, teacher=com.hard.qz.clone.Teacher@1b6d3586}
clone后的Student对象为:Student{sname='学生1', sage=18, teacher=com.hard.qz.clone.Teacher@1b6d3586}
Student对象与cloneStudent对象是否相等:false
student对象和cloneStudent对象中的teacher属性是否相等:true
//修改student对象中teacher属性的值,观察cloneStudent对象中的teacher属性的值是否会变
student.getTeacher().setTname("张三老师");
System.out.println("cloneStudent对象中teacher属性的值为:"+cloneStudent.getTeacher());

El resultado es:

cloneStudent对象中teacher属性的值为:Teacher{tname='张三老师'}

Al modificar el valor del atributo profesor en el objeto estudiante, afectará el valor del atributo profesor en el objeto clonEstudent Esto muestra que: dos objetos estudiante comparten un objeto profesor.image.png

En el caso anterior, al copiar, solo se copian algunas propiedades, y cuando no se copian las propiedades del objeto y la matriz, esta copia se denomina copia superficial.

¿Qué es una copia profunda?

Al copiar, se copian todas las propiedades de un objeto, incluidas las propiedades del objeto y de la matriz. Esta copia se denomina copia profunda.

¿Cómo implementar una copia profunda?

Al anular el método de clonación, se puede lograr una copia profunda llamando al método de clonación en las propiedades del objeto y la matriz. La propiedad Object del objeto copiado es necesaria para implementar también la interfaz Cloneable, y el método de clonación se anula.

//Teacher类实现了Cloneable接口,重写了clone方法
public class Teacher implements Cloneable{

    private String tname;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

//Student类重写clone方法时,调用了Teacher类的clone方法,实现深拷贝
@Override
protected Student clone() throws CloneNotSupportedException {
    Student cloneStudent = (Student) super.clone();
    cloneStudent.setTeacher((Teacher) cloneStudent.getTeacher().clone());
    return cloneStudent;
}

Copie el objeto del estudiante y compare si los dos objetos y las propiedades del objeto son iguales.

public class cloneObject {
    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher teacher = new Teacher("罗翔老师");
        Student student = new Student("学生1",18,teacher);
        System.out.println("clone前的Student对象为:"+student);
        Student cloneStudent = student.clone();
        System.out.println("clone后的Student对象为:"+cloneStudent);
        System.out.println("Student对象与cloneStudent对象是否相等:"+student.equals(cloneStudent));
        System.out.println("student对象和cloneStudent对象中的teacher属性是否相等:"+student.getTeacher().equals(cloneStudent.getTeacher()));

        //修改student对象中teacher属性的值,观察cloneStudent对象中的teacher属性的值是否会变
        student.getTeacher().setTname("张三老师");
        System.out.println("cloneStudent对象中teacher属性的值为:"+cloneStudent.getTeacher());
    }
}

El resultado de la impresión es

clone前的Student对象为:Student{sname='学生1', sage=18, teacher=Teacher{tname='罗翔老师'}}
clone后的Student对象为:Student{sname='学生1', sage=18, teacher=Teacher{tname='罗翔老师'}}
Student对象与cloneStudent对象是否相等:false
student对象和cloneStudent对象中的teacher属性是否相等:false
cloneStudent对象中teacher属性的值为:Teacher{tname='罗翔老师'}

El resultado de la impresión muestra que los dos objetos y sus propiedades después de la copia en profundidad no son iguales.

image.png

Resumir

  1. Copiar es crear un nuevo objeto basado en el metaobjeto para reutilizar algunas o todas las propiedades del objeto original.
  2. 浅拷贝是拷贝后两个对象地址不相等,但两个对象的部分属性地址相等,新对象并没有拷贝所有的属性,而是复用原对象中的值。
  3. 深拷贝是拷贝后两个对象不仅地址不相等,两个对象的所有属性地址都不相等。

Supongo que te gusta

Origin juejin.im/post/7120876548088922143
Recomendado
Clasificación