对象copy的两种方式--序列化--clone
对象实现copy有多中方式,最土的方法就是直接new,然后塞值,不过这种方法是真的low,下面着重说说Object类中的clone() 和 序列化反序列化copy
Object 中 clone的方法
1.Object中clone 方法是protected,虽然所有类都继承自object 但是在不同包下调用还是不被允许的,因此要重写clone方法。
2.调用clone方法clone对象时要求对象实现Cloneable接口,否则会抛出 CloneNotSupportedException
/** @return a clone of this instance. * @throws CloneNotSupportedException if the object's class does not * support the {@code Cloneable} interface. Subclasses * that override the {@code clone} method can also * throw this exception to indicate that an instance cannot * be cloned. * @see java.lang.Cloneable */ protected native Object clone() throws CloneNotSupportedException;
clone 方法可以实现对象的浅copy ,什么是浅copy 举个例子
人 有 头 和 名字 两个属性 , 头 又有 头发 属性 ,现在使用clone方法 克隆一个人,则clone出来的人和原有的人是两个对象,但是发现两个人的头在内存中只有一个,也就是说,clone出来的人使用了原有人的头对象。如果改了其中一个对象头对象的属性,另一个也会跟着变。
序列化和反序列化,将对象读到内存中,在从内存中读取出来
需要对象实现 Serializable 接口
直接上代码了,自己跑即可:
import lombok.extern.slf4j.Slf4j; import java.io.*; /** * @ClassName CommonUtils * @Description <工具类></> * @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt * @Date 2018/12/4 11:39 * @Version 1.0 */ @Slf4j public class CommonUtils { /** * @return T * @Description <深度克隆对象,对象需要序列化> * @Author Zhaiyt * @Date 14:11 2018/12/4 * @Param [obj] **/ public static <T extends Serializable> T clone(T obj) { try { //将对象读取到内存中 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream); outputStream.writeObject(obj); //从内存中读取 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); return (T) objectInputStream.readObject(); } catch (IOException e) { log.error("clone Object IOException"); } catch (ClassNotFoundException e) { log.error("clone Object ClassNotFoundException"); } return null; } public static void main(String[] args) { Person p = new Person(); p.setName("zhangsan"); p.setSix("男"); Head h = new Head(); h.setHair("black"); p.setHead(h); Person cloneP = clone(p); System.out.println("深copy对象的属性 p.head 和 cloneP.head 是否相等"); System.out.println(p.getHead().equals(cloneP.getHead())); //浅copy Person clone; try { clone = (Person) p.clone(); System.out.println("浅copy对象的属性 p.head 和 clone.head"); System.out.println(p.getHead().equals(clone.getHead())); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } } /** * @ClassName <Person> * @Description <人对象> * @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt * @Date 2018/12/4 16:12 * @Version 1.0 */ class Person implements Serializable, Cloneable { private String name; private String six; private Head head; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSix() { return six; } public void setSix(String six) { this.six = six; } public Head getHead() { return head; } public void setHead(Head head) { this.head = head; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", six='" + six + '\'' + ", head=" + head + '}'; } } /** * @ClassName <Head> * @Description <人的属性> * @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt * @Date 2018/12/4 16:11 * @Version 1.0 */ class Head implements Serializable { private String hair; public String getHair() { return hair; } public void setHair(String hair) { this.hair = hair; } @Override public String toString() { return "Head{" + "hair='" + hair + '\'' + '}'; } }
序列化和反序列化后出来的对象发现属性对象不再是同一个对象了。