一、深拷贝和浅拷贝简单介绍
首先,我们要知道,深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。
浅拷贝:浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,换句话说,浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变。
深拷贝:深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
下面用一副图来加深理解:
二、探究clone是深拷贝还是浅拷贝
创建一个People类
public class Person implements Cloneable{
public String name;
public Address address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
创建一个Address类,将该类的实例化对象作为People的一个属性
public class Address {
public String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
再创建一个测试类,将c1通过clone方法复制出c2
public class Copy{
public static void main(String[] args) throws CloneNotSupportedException {
Person c1 = new Person();
Address ad = new Address();
ad.setValue("广州");
c1.setAddress(ad);
System.out.println(c1.getAddress().getValue());
Person c2 = (Person) c1.clone();
c2.getAddress().setValue("上海");
System.out.println(c1.getAddress().getValue());
}
}
运行结果:
广州
上海
从这结果就知道了,明明只是c2改变了address,但是c1的address也发生了改变,说明clone是浅拷贝的。
而如果要将clone方法变成深拷贝,那么就需要重写clone方法。
三、Arrays.copyOf是深拷贝还是浅拷贝
import java.util.Arrays;
public class Copy{
public static void main(String[] args) throws CloneNotSupportedException {
Student[] stu1=new Student[1];
stu1[0]=new Student("李白");
System.out.println(stu1[0].getName());
Student[] stu2;
stu2 = Arrays.copyOf(stu1, 1);
System.out.println(stu2[0].getName());
stu2[0].setName("杜甫");
System.out.println(stu2[0].getName());
System.out.println(stu1[0].getName());
}
}
李白
李白
杜甫
杜甫
当stu2改变时,stu1的名字也发生了改变,由此说明Arrays.copyOf是浅拷贝。
四、System.arraycopy是深拷贝还是浅拷贝
import java.util.Arrays;
public class Copy{
public static void main(String[] args) throws CloneNotSupportedException {
Student[] stu1=new Student[1];
stu1[0]=new Student("李白");
System.out.println(stu1[0].getName());
Student[] stu2=new Student[1];
System.arraycopy(stu1, 0, stu2, 0, 1);
System.out.println(stu2[0].getName());
stu2[0].setName("杜甫");
System.out.println(stu2[0].getName());
System.out.println(stu1[0].getName());
//System.arraycopy(src, srcPos, dest, destPos, length);
}
}
当stu2改变时,stu1的名字也发生了改变,由此说明System.arraycopy是浅拷贝。