我正在回顾Java的一些基本方面,并对浅克隆和深克隆有一些疑问。我很了解他们,并且了解内部原理。但是我偶然发现了这个简单的练习-

部门课-

public class Department {
    String deptName;

    public String getdName() {
        return deptName;
    }

    public void setdName(String dName) {
        this.deptName = dName;
    }

    public Department() {
        super();
    }

    public Department(String dName) {
        super();
        this.deptName = dName;
    }
}


员工阶层-

public class Employee implements Cloneable{
    int empNo;
    String empName;
    Department dept;

    public int getEmpNo() {
        return empNo;
    }
    public void setEmpNo(int empNo) {
        this.empNo = empNo;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }
    public Department getDept() {
        return dept;
    }
    public void setDept(Department dept) {
        this.dept = dept;
    }
    public Employee(int empNo, String empName, Department dept) {
        super();
        this.empNo = empNo;
        this.empName = empName;
        this.dept = dept;
    }
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}


主类-

public class ShalowCopyTest {

    public static void main(String args[]) {
        Department dept1 = new Department("Development");
        Department dept2 = new Department("Testing");
        Employee emp1 = new Employee(10, "Peter", dept1);
        Employee emp2 = null;
        try {
            emp2 = (Employee) emp1.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        System.out.println(emp1.getDept().getdName());
        System.out.println(emp2.getDept().getdName());

        System.out.println("Now changing emp1.dept");
        //emp1.setDept(dept2); //This is deep cloning - why?
        emp1.getDept().setdName("Testing"); //This is shallow cloning
        System.out.println(emp1.getDept().getdName());
        System.out.println(emp2.getDept().getdName());
    }
}


您可以看到,如果我使用emp1.setDept(dept2),则更改emp1的dept对emp2无效。所以这是深克隆。但是仅通过emp1.getDept()。setdName(“ Testing”)更改dName也会使emp2的dName更改。所以这是浅克隆。为什么这两行会有所作为?为什么它们不一样?
谢谢。

最佳答案

我注意到您正在使用与此链接相同的示例:A Guide to Object Cloning in Java

可能您已经知道super.clone()的默认实现会执行“浅复制”而不是“深复制”。

在这种情况下,两个对象实例:emp1和emp2将包含指向内存中相同位置的引用。
引用Department实例,这是克隆emp1对象后在内存中的引用方式:
java - 浅克隆和深克隆-LMLPHP
两者都指向内存中的同一位置,其中包含一个不变的字符串:“开发”。

通过设置:

emp1.setDept(dept2);


它将emp1的引用更改为新对象dept2:
java - 浅克隆和深克隆-LMLPHP

在这种情况下,您会将其视为深度复制,但实际上并非如此。只是emp1更改了它对内存中新位置的引用。

在另一种情况下,设置时:

emp1.getDept().setdName("Testing");


您将Departman的名称更改为“ Testing”-对两个对象实例均可见。

如果您还有其他问题,请告诉我。

10-04 11:52