java中的深复制和浅复制

参考:
Java如何复制对象

总结:
1.我们平常使用的让一个对象等于另外一个对象,如:

Student a=new Student("A");
Student b=a;

这个复制其实是对对象引用的复制,复制后a和b都指向了堆中的同一个对象,当b修改时a也会跟着被修改。

b.setname("B");
System.out.println(a.name);
System.out.println(b.name);

以上输出都是B。可以看到复制的对象和原对象之间是互相影响的。

2.所谓的浅复制,顾名思义就是比较浅的复制,不彻底的复制,当我们浅复制一个对象的时候,我们复制了它的所有的东西,但里面的情况有差别,可以分为两类:
a.所有实例域和不可变类成员对象,比如八种基本数据类型和String类型,这些东西复制之后,在副本中修改不会影响原对象的这些属性的值
b.可变成员对象,如Date对象,还是复制它的引用,也就是说副本和原对象之间还是互相影响的。
举例:

class Student implements Cloneable{  
    private int number;  
  
    public int getNumber() {  
        return number;  
    }  
  
    public void setNumber(int number) {  
        this.number = number;  
    }  
      
    @Override  
    public Object clone() {  
        Student stu = null;  
        try{  
            stu = (Student)super.clone();  
        }catch(CloneNotSupportedException e) {  
            e.printStackTrace();  
        }  
        return stu;  
    }  
}  
public class Test {  
      
    public static void main(String args[]) {  
          
        Student stu1 = new Student();  
        stu1.setNumber(12345);  
        Student stu2 = (Student)stu1.clone();  
          
        System.out.println("学生1:" + stu1.getNumber());  
        System.out.println("学生2:" + stu2.getNumber());  
          
        stu2.setNumber(54321);  
      
        System.out.println("学生1:" + stu1.getNumber());  
        System.out.println("学生2:" + stu2.getNumber());  
    }  
}  

输出:

学生1:12345  
学生2:12345  
学生1:12345  
学生2:54321  

这时候我们发现复制1的2修改学号后,1的学号并没有因此而改变,这说明了这些东西都被复制到了一个新的内存空间中。
又比如:

class Address  {  
    private String add;  
  
    public String getAdd() {  
        return add;  
    }  
  
    public void setAdd(String add) {  
        this.add = add;  
    }  
      
}  
  
class Student implements Cloneable{  
    private int number;  
  
    private Address addr;  
      
    public Address getAddr() {  
        return addr;  
    }  
  
    public void setAddr(Address addr) {  
        this.addr = addr;  
    }  
  
    public int getNumber() {  
        return number;  
    }  
  
    public void setNumber(int number) {  
        this.number = number;  
    }  
      
    @Override  
    public Object clone() {  
        Student stu = null;  
        try{  
            stu = (Student)super.clone();  
        }catch(CloneNotSupportedException e) {  
            e.printStackTrace();  
        }  
        return stu;  
    }  
}  
public class Test {  
      
    public static void main(String args[]) {  
          
        Address addr = new Address();  
        addr.setAdd("杭州市");  
        Student stu1 = new Student();  
        stu1.setNumber(123);  
        stu1.setAddr(addr);  
          
        Student stu2 = (Student)stu1.clone();  
          
        System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
        System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  
        addr.setAdd("西湖区");  
  
        System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
        System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  
    }  
}  

输出:

学生1:123,地址:杭州市  
学生2:123,地址:杭州市
学生1:123,地址:西湖区  
学生2:123,地址:西湖区   

这时候发现add成员变量是互相影响的,这种复制就不彻底,对象间还有牵连。

3.所谓的深复制,就是彻底的复制,在浅复制的基础上,使得类中的成员变量复制之后也没有牵连。

@Override  
    public Object clone() {  
        Student stu = null;  
        try{  
            stu = (Student)super.clone();   //浅复制  
            stu.addr = (Address)addr.clone();   //深度复制  
        }catch(CloneNotSupportedException e) {  
            e.printStackTrace();  
        } 
        return stu;  
    }  

将studen类中的clone方法改成以上就可以了,

你可能感兴趣的:(java中的深复制和浅复制)