Java的深拷贝和浅拷贝,我用一个最直接的例子来说明,需要执行代码直接拷贝过去,直接执行。
浅拷贝:重写clone()方法,返回super.clone()方法,该方法在对象调用时候默认返回的就是浅拷贝,浅拷贝时只拷贝对象本身和对象的基本变量,对象的引用变量不会进行拷贝,还是指向原来的对象。
深拷贝:需要重写clone()方法,我在代码中已经注释掉了,如果该类有多个对象引用,需要都进行clone重写,因为每次clone都是跟之前对象的地址是不同的,所以对象是使用==比较符是不相等返回false。
/**
* @author 冉野 E-mail:yangtianrui135@163.com
* @version 创建时间:18/9/29 下午5:55
*/
public class CloneableTest2 implements Cloneable {
private String name;
private CloneableTest cloneableTest;
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public CloneableTest getCloneableTest() {
return cloneableTest;
}
public void setCloneableTest(CloneableTest cloneableTest) {
this.cloneableTest = cloneableTest;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CloneableTest2)) return false;
CloneableTest2 that = (CloneableTest2) o;
return Objects.equals(getName(), that.getName()) &&
Objects.equals(getCloneableTest(), that.getCloneableTest());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getCloneableTest());
}
// 深拷贝时候的重写clone()方法
@Override
protected Object clone() throws CloneNotSupportedException {
CloneableTest2 cloneableTest2 = (CloneableTest2) super.clone();
cloneableTest2.cloneableTest = (CloneableTest) cloneableTest2.getCloneableTest().clone();
return cloneableTest2;
}
// 浅拷贝时候clone()方法
// @Override
// protected Object clone() throws CloneNotSupportedException {
// return super.clone();
// }
public static void main(String[] args) {
CloneableTest2 cl1 = new CloneableTest2();
CloneableTest cloneableTest = new CloneableTest("1",1);
cl1.setCloneableTest(cloneableTest);
CloneableTest2 cl2 = null;
try {
// 浅拷贝是指在对象拷贝时候仅仅是拷贝对象本身和基本变量 关于对象的引用类型变量不进行拷贝
cl2 = (CloneableTest2) cl1.clone();
System.out.println(cl1.equals(cl2)); // true
System.out.println(cl1.getClass() == cl2.getClass()); // true
System.out.println(cl1 == cl2); // false
// 拷贝时 每次都是新的对象 所以 == 比较总是返回false
System.out.println(cl1.getCloneableTest()==cl2.getCloneableTest());// false
// 引用类型的变量 还是执行原来的对象 没发生改变 但是深拷贝就会改变
// 构造方法链 子类在调用自己构造方法前 如果继承父类 会先使用父类的构造方法 如果父类还继承了别的类 则
// 也会先调用该父类的构造方法
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
CloneableTest类
public class CloneableTest implements Cloneable{
private String name;
private int age;
public CloneableTest(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CloneableTest)) return false;
CloneableTest that = (CloneableTest) o;
return age == that.age &&
Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}