深拷贝和浅拷贝
拷贝对象: 实现cloneable接口,重写clone方法。因为Object里的clone方法是protected的。
浅拷贝:
浅拷贝就是拷贝对象里面的对象引用没有被拷贝,还是指向地址。 --下面就是演示 person里面的hobby对象没有被拷贝。还是指向地址
Person类:
@Data public class Person implements Cloneable{ private String name; private int age; private Hobby hobby; public Person(String name, int age, Hobby hobby) { this.name = name; this.age = age; this.hobby = hobby; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", hobby.like=" + hobby.getLike() + ", hobby.hate=" + hobby.getHate() + '}'; } }
Hobby类 -- person里的引用,也就是这个不能被拷贝
@Data public class Hobby implements Cloneable{ private String like; private String hate; public Hobby(String like, String hate) { this.like = like; this.hate = hate; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
测试类:
public class CloneableTest { public static void main(String[] args) throws Exception{ Person p1 = new Person("shishi", 16, new Hobby("eat", "work")); Person p2 = (Person)p1.clone(); System.out.println(p1); System.out.println(p2); System.out.println(p1 == p2); //注意这里修改了p2,但是p1对象也是hard work,说明是浅拷贝。这个hobby对象没有真正被拷贝,而是引用地址。 p2.getHobby().setHate("hard work"); System.out.println(p1); System.out.println(p2); } }
测试结果:
深拷贝:
就是重写clone方法的时候,里面的对象引用也要clone
@Data public class Person implements Cloneable{ private String name; private int age; private Hobby hobby; public Person(String name, int age, Hobby hobby) { this.name = name; this.age = age; this.hobby = hobby; } @Override protected Object clone() throws CloneNotSupportedException { Object o = null; o = super.clone(); Person p = (Person)o; p.hobby = (Hobby)p.getHobby().clone(); return o; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", hobby.like=" + hobby.getLike() + ", hobby.hate=" + hobby.getHate() + '}'; } }
再用上面的那段代码测试,就实现了深拷贝: