What?
浅拷贝和深拷贝发生在对象和对象之间,假设你需要将一个对象的值赋予给另一个对象,这个过程就叫做拷贝。那么拷贝的过程中,对象的属性中可能既有普通变量也有对象,能够复制后副本对象的引用指向新地址的就是深拷贝,仍指向旧的地址那一般也就是浅拷贝了。
How?
1.重写clone方法
对于拷贝的一个办法就是重写cloneable类的clone方法,参考下面的示例:
浅拷贝:
public class Address implements Cloneable{ private String name; @Override public Address clone(){ try{ return (Address) super.clone(); }catch(CloneNotSupportedException e){ throw new AssertionError(); } } } public class Person implements Cloneable{ private String name; private Address address; @Override public Person clone(){ try{ Person p = (Person) super.clone(); return p; }catch(CloneNotSupportedException e){ throw new AssertionError(); } } }以上代码展示的就是浅拷贝。
深拷贝:
public class Person implements cloneable throws CloneNotSupportedException{ @Override public Person clone(){ try{Person person = (Person) super.clone(); person.setAddress(person.getAddress().clone()); return person; }catch(CloneNotSupportedException e){ throw new AssertionError(); } } }2.序列化进行拷贝(深拷贝)
class Person implements Serializable{ private String name; private Address address; public Person deepCopy(){ try{ ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); oos.flush(); oos.close(); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return (Person) ois.readObject(); }catch(IOException | ClassNotFoundException e){ e.printStackTrace(); return null; } } class Address implements Serializable { private static final long seriaVersionUTI = 1L; } }这块可以对Java IO部分的内容进行复习回顾,比如什么是装饰者模式?
手动递归复制
class Person{ private String name; private Address address; public Person deepCopy(){ Person copy = new Person(); copy.setName(this.name); copy.setAddress(this.address.deepCopy()); return copy; } } class Address{ private int code; public Address deepCopy(){ Address copy = new Address(); copy.setCode(this.code); return copy; } }总结:
浅拷贝:
- 重写Cloneable类的clone方法
深拷贝:
- 重写Cloneable类的clone方法
- 继承Serializable类后利用序列化和反序列化
- 手动递归调用deepCopy方法