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方法改成以上就可以了,

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 属性中copy与strong特性的区别 在开始学习浅复制(Shallow Copy)、深复制(Deep Co...
    pro648阅读 1,757评论 2 16
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,742评论 18 399
  • 在OC编程中,常常会用到对对象的复制,然后操作副本对象。然而对与应该选择何种对象复制的方式,复制后副本对象操作会不...
    Jiao123阅读 7,116评论 4 5
  • 上周四晚上在某某网下单买的书,周一在办公室等了一天仍旧没有收到。忙忙碌碌的工作结束后,查看物流记录显示配送失败。 ...
    小easy阅读 147评论 1 0
  • 你的内心够强大吗?何为内心强大,怎么才能练就强大内心? 内心强大并不意味着压抑自己的情绪、做个无坚不摧的人,更不意...
    田螺姑娘22阅读 887评论 0 0