浅复本:
表述比如说A被B浅复本后,B的大部份表达式和A的大部份表达式完全相同,所以B大部份对其它第一类的提及吴垂昆对准原本的第一类,也是对像浅复本只会对主第一类(是A)这类展开复本,但不能对主第一类里头的第一类复本,A和B里面的第一类提及完全相同,归属于共享资源状况。
单纯说是,缴付至所考量的第一类,而不拷贝它提及的第一类。
浅复本大前提具体来说第一类浅复本须要同时实现USBCloneable
CloneableUSB
空USB
Cloneable是记号型的USB(空USB),它外部都没方式和特性,同时实现 Cloneable来则表示该第一类能被布季夫,能采用Object.clone()方式。假如没同时实现 Cloneable的类第一类初始化clone()就
CloneNotSupportedException极度。能认知为CloneableUSB充分发挥的是记号机能,自订类别须要采用者他们记号出甚么样类是能clone的,那个记号是去同时实现CloneableUSB,同时实现了CloneableUSB后就说明此类建立的第一类能被布季夫。而要想使两个类具有复本示例的机能,除要同时实现CloneableUSB,还要改写Object类的clone()方式。标识符简述Group类同时实现:
super.clone()他会把原第一类完备的复本回来主要包括当中的提及,归属于欠复本
接掌里是Group和Person类,用作浅复本
package com.consumer.test; public class Group implements Cloneable{ String groupName; Person person; public String getGroupName() { returngroupName; }public void setGroupName(String groupName) { this.groupName = groupName; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @Override protected Object clone() throws CloneNotSupportedException { Object object = super.clone(); returnobject; } }package com.consumer.test; public class Person implements Cloneable{ String name; String sex;public String getName() { return name; } public void setName(String name) { this.name = name; }public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }具体同时实现样例类ShallowCopypublic class ShallowCopy { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); person.setName(“zhangSan”); person.setSex(“17”); Groupgroup = new Group(); group.setGroupName(“1号组”); group.setPerson(person); Group groupCopy = (Group)group.clone(); System.out.println(“浅复本后:”); System.out.println(groupCopy.getGroupName()); System.out.println(groupCopy.getPerson().getName()); System.out.println(groupCopy.getPerson().getSex()); System.out.println(“修改Person信息后:”); person.setName(“liSi”); person.setSex(“28”); group.setGroupName(“copy组”); System.out.println(groupCopy.getGroupName()); System.out.println(groupCopy.getPerson().getName()); System.out.println(groupCopy.getPerson().getSex()); } }运行结果
从结果发现浅复本后拷贝得到的第一类提及的person会随着原第一类的改变而变化,但是直接特性String不能随着原第一类的修改儿变化。
浅复本特点总结:
1.拷贝得到的第一类这类是新对象
2.第一类里头的基本数据会拷贝, 基本数据不存在提及;特殊的String类别,有深复本表现;
String 存在于堆内存、常量池;这种比较特殊, 这类没同时实现 Cloneable, 传递是提及地址;
由本身的final性, 每次赋值都是两个新的提及地址,原第一类的提及和副本的提及互不影响。
因此String就和基本数据类别一样,表现出了”深复本”特性.
3.第一类里头的复杂数据类别会展开浅复本, 对准的同两个提及地址
深复本:
DeepGroup
package com.consumer.test; public class DeepGroup implements Cloneable{ String groupName; Person person;public String getGroupName() { return groupName; } public void setGroupName(String groupName) { this.groupName = groupName; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @Override protected Object clone() throwsCloneNotSupportedException{ DeepGroup deepGroup = (DeepGroup)super.clone(); // 本来是浅拷贝的,现在讲Person镀锌拷贝一份重新set进来,因为都是基本类别,都支持深复本 deepGroup.setPerson((Person) deepGroup.getPerson().clone()); returndeepGroup; } }Person
package com.consumer.test; public class Person implements Cloneable{ String name; String sex;public String getName() { return name; } public void setName(String name) { this.name = name; }public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } 具体深复本示例:packagecom.consumer.test;public class DeepGroup implements Cloneable{ String groupName; Person person; public String getGroupName() { return groupName; } public void setGroupName(String groupName) { this.groupName = groupName; }public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @Override protected Object clone() throws CloneNotSupportedException { DeepGroup deepGroup = (DeepGroup)super.clone(); // 本来是浅拷贝的,现在讲Person镀锌拷贝一份重新set进来,因为都是基本类别,都支持深复本deepGroup.setPerson((Person) deepGroup.getPerson().clone());return deepGroup; } }运行结果:
深复本结果
我们发现深复本后,拷贝得到的第一类不能受到原本第一类的修改而变化的影响了。
深复本总结:
大部份特性都是一份复本, 跟原数据不能有任何耦合(不存在提及共享资源),我们目前是一层层浅复本,同时实现深复本,假如嵌套层次很多会很臃肿,当然我们能格式化深复本: 不须要递归让大部份第一类同时实现cloneableUSB, 方便简洁。
贴上深复本工具类:(此工具类的复本类要都是同时实现了SerializableUSB,支持格式化,否则会报错)
package com.consumer.test; import java.io.*;public class CloneUtils { @SuppressWarnings(“unchecked”) public static <T extends Serializable> T deepClone(T obj) { T cloneObj = null; try { //写入字节流ByteArrayOutputStreamout = new ByteArrayOutputStream(); ObjectOutputStream obs = new ObjectOutputStream(out); obs.writeObject(obj); obs.close();//分配内存,写入原始第一类,生成新第一类 ByteArrayInputStream ios = newByteArrayInputStream(out.toByteArray()); ObjectInputStream ois = new ObjectInputStream(ios); //返回生成的新第一类cloneObj = (T) ois.readObject(); ois.close(); }catch (Exception e) { e.printStackTrace(); } returncloneObj; } }格式化同时实现深复本同时实现:
package com.consumer.test; import com.alibaba.fastjson.JSONObject;public class DeepTest { public static void main(String[] args) throws Exception { Person person = newPerson(); person.setName(“zhangSan”); person.setSex(“17”); DeepGroup deepGroup = newDeepGroup(); deepGroup.setGroupName(“1号组”); deepGroup.setPerson(person); // 格式化——深复本 // 相当于改写字节流, 再建立新第一类, 跟原第一类没任何提及共享资源, 无需嵌套重现 Cloneable.clone(), 只须要同时实现 Serializable (每个子类) System.out.println(“—————– 格式化-深复本测试1 ——————“); // 工具类DeepGroup deepGroupCopy = CloneUtils.deepClone(deepGroup); System.out.println(“deepGroup == deepGroupCopy: “+ (deepGroup == deepGroupCopy)); System.out.println(“deepGroup.person == deepGroupCopy.person: “+ (deepGroup.getPerson() == deepGroupCopy.getPerson())); System.out.println(“deepGroup.person.name == deepGroupCopy.person.name: “+ (deepGroup.getPerson().getName() == deepGroupCopy.getPerson().getName())); System.out.println(JSONObject.toJSONString(deepGroup)); System.out.println(JSONObject.toJSONString(deepGroupCopy)); System.out.println(“—————– 格式化-深复本测试2 ——————“); person.setName(“liSi”); person.setSex(“132”); System.out.println(JSONObject.toJSONString(deepGroup)); System.out.println(JSONObject.toJSONString(deepGroupCopy)); } }运行结果:
我们发现格式化能同时实现深复本,没问题,到此ok。