浅克隆、深克隆
来源:互联网 发布:用二分法求根C语言 编辑:程序博客网 时间:2024/04/28 20:45
// ———-1、直接复制对象 ———–
package ninthTestModel;/* * 浅克隆 * 深克隆 * 序列化。 * 区别在于对象有引用对象的时候 一个是指向同一个引用对象 一个是指向不同对象 *//* * * 【浅克隆】,通常只是对克隆的实例进行复制,但里面的其他子对象,都是共用的。 * 【深克隆】,克隆的时候会复制它的子对象的引用,里面所有的变量和子对象都是又额外拷贝了一份。 * */// 周报class WeekdayInformation{ public String strInformation; // 事件 public String strTime; // 时间 public String strLocation; // 地点 public String getStrInformation() { return strInformation; } public String getStrTime() { return strTime; } public String getStrLocation() { return strLocation; } public void setStrInformation(String strInformation) { this.strInformation = strInformation; } public void setStrTime(String strTime) { this.strTime = strTime; } public void setStrLocation(String strLocation) { this.strLocation = strLocation; } @Override public String toString() { // TODO Auto-generated method stub return "事件:"+strInformation+"\t时间:"+strTime+"\t地点:"+strLocation; }}public class CloneModel { public static void main(String[] args) { // TODO Auto-generated method stub WeekdayInformation weekdayInformation=new WeekdayInformation(); weekdayInformation.setStrInformation("吃饭"); weekdayInformation.setStrTime("周一"); weekdayInformation.setStrLocation("食堂"); System.out.println(weekdayInformation.toString()); // ninthTestModel.WeekdayInformation@2a139a55 WeekdayInformation week2=weekdayInformation; System.out.println(week2.toString()); System.out.println("***********************"); /* * weekdayInformation修改信息 则week2的信息也修改 */ System.out.println("weekdayInformation修改了信息:"); weekdayInformation.setStrTime("周二"); System.out.println(weekdayInformation.toString()); System.out.println(week2.toString()); System.out.println("***********************"); /* * week2修改信息 则weekdayInformation的信息也修改 */ System.out.println("week2修改了信息:"); week2.setStrTime("周一"); System.out.println(weekdayInformation.toString()); System.out.println(week2.toString()); }}/*结果如下:事件:吃饭 时间:周一 地点:食堂事件:吃饭 时间:周一 地点:食堂***********************weekdayInformation修改了信息:事件:吃饭 时间:周二 地点:食堂事件:吃饭 时间:周二 地点:食堂***********************week2修改了信息:事件:吃饭 时间:周一 地点:食堂事件:吃饭 时间:周一 地点:食堂*/
// ——–2、浅克隆 里面没有引用对象—
package ninthTestModel;/* * 浅克隆 * 深克隆 * 序列化。 * 区别在于对象有引用对象的时候 一个是指向同一个引用对象 一个是指向不同对象 *//* * * 【浅克隆】,通常只是对克隆的实例进行复制,但里面的其他子对象,都是共用的。 * 【深克隆】,克隆的时候会复制它的子对象的引用,里面所有的变量和子对象都是又额外拷贝了一份。 * */// 周报class WeekdayInformation implements Cloneable{ public String strInformation; // 事件 public String strTime; // 时间 public String strLocation; // 地点 public String getStrInformation() { return strInformation; } public String getStrTime() { return strTime; } public String getStrLocation() { return strLocation; } public void setStrInformation(String strInformation) { this.strInformation = strInformation; } public void setStrTime(String strTime) { this.strTime = strTime; } public void setStrLocation(String strLocation) { this.strLocation = strLocation; } // 浅克隆 @Override protected WeekdayInformation clone() throws CloneNotSupportedException { // TODO Auto-generated method stub Object object=null; object=super.clone(); System.out.println("浅克隆"); return (WeekdayInformation) object; // TODO Auto-generated catch block } @Override public String toString() { // TODO Auto-generated method stub return "事件:"+strInformation+"\t时间:"+strTime+"\t地点:"+strLocation; }}public class CloneModel { public static void main(String[] args) throws CloneNotSupportedException { // TODO Auto-generated method stub WeekdayInformation weekdayInformation=new WeekdayInformation(); weekdayInformation.setStrInformation("吃饭"); weekdayInformation.setStrTime("周一"); weekdayInformation.setStrLocation("食堂"); System.out.println(weekdayInformation.toString()); // ninthTestModel.WeekdayInformation@2a139a55 WeekdayInformation week2=weekdayInformation.clone(); System.out.println(week2.toString()); System.out.println("***********************"); /* * weekdayInformation修改信息 则week2的信息也修改 */ System.out.println("weekdayInformation修改了信息:"); weekdayInformation.setStrTime("周二。"); System.out.println(weekdayInformation.toString()); System.out.println(week2.toString()); System.out.println("***********************"); /* * week2修改信息 则weekdayInformation的信息也修改 */ System.out.println("week2修改了信息:"); week2.setStrTime("周三。"); System.out.println(weekdayInformation.toString()); System.out.println(week2.toString()); }}结果如下:/* 事件:吃饭 时间:周一 地点:食堂 浅克隆 事件:吃饭 时间:周一 地点:食堂 *********************** weekdayInformation修改了信息: 事件:吃饭 时间:周二。 地点:食堂 事件:吃饭 时间:周一 地点:食堂 *********************** week2修改了信息: 事件:吃饭 时间:周二。 地点:食堂 事件:吃饭 时间:周三。 地点:食堂*/
// ———-3、浅克隆 里面有被引用对象
package ninthTestModel;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.OptionalDataException;import java.io.Serializable;import sixTestOop.TestEighthToString;/* * 浅克隆 * 深克隆 * 序列化。 * 区别在于对象有引用对象的时候 一个是指向同一个引用对象 一个是指向不同对象 *//* * * 【浅克隆】,通常只是对克隆的实例进行复制,但里面的其他子对象,都是共用的。 * 【深克隆】,克隆的时候会复制它的子对象的引用,里面所有的变量和子对象都是又额外拷贝了一份。 * 注:!序列化问题 因为使用了序列化方法实现深克隆 因此类需要继承Serializable 引用类也需要继承 */class TestClone implements Serializable{ public String testString; public void setTestString(String testString) { this.testString = testString; } public String getTestString() { return testString; }}// 周报class WeekdayInformation implements Cloneable,Serializable{ public String strInformation; // 事件 public String strTime; // 时间 public String strLocation; // 地点 public TestClone strClone; // 被引用对象 public String getStrInformation() { return strInformation; } public String getStrTime() { return strTime; } public String getStrLocation() { return strLocation; } public TestClone getStrClone() { return strClone; } public void setStrInformation(String strInformation) { this.strInformation = strInformation; } public void setStrTime(String strTime) { this.strTime = strTime; } public void setStrLocation(String strLocation) { this.strLocation = strLocation; } public void setStrClone(TestClone strClone) { this.strClone = strClone; } // 浅克隆 @Override protected WeekdayInformation clone() throws CloneNotSupportedException { // TODO Auto-generated method stub Object object=null; object=super.clone(); System.out.println("浅克隆"); return (WeekdayInformation) object; } // 深克隆 public WeekdayInformation deepClone() throws IOException, ClassNotFoundException,OptionalDataException { System.out.println("******深克隆*********\n"); WeekdayInformation weekdayInformation=null; // -- 将对象写入流中 ByteArrayOutputStream bao=new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bao); oos.writeObject(this); oos.close(); // -- 将对象从流中取出 ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray()); ObjectInputStream ois=new ObjectInputStream(bis); weekdayInformation=(WeekdayInformation) ois.readObject(); ois.close(); return weekdayInformation; } @Override public String toString() { // TODO Auto-generated method stub return "事件:"+strInformation+"\t时间:"+strTime+"\t地点:"+strLocation+"\t测试:"+strClone.getTestString(); }}public class CloneModel { public static void main(String[] args) throws CloneNotSupportedException, OptionalDataException, ClassNotFoundException, IOException { // TODO Auto-generated method stub WeekdayInformation weekdayInformation=new WeekdayInformation(); TestClone testClone=new TestClone(); testClone.setTestString("test"); weekdayInformation.setStrInformation("吃饭"); weekdayInformation.setStrTime("周一"); weekdayInformation.setStrLocation("食堂"); weekdayInformation.setStrClone(testClone); System.out.println(weekdayInformation.toString()); //如果没重写toString()方法显示: ninthTestModel.WeekdayInformation@2a139a55 WeekdayInformation week2 = weekdayInformation.clone(); System.out.println("克隆信息如下:"+week2+"\n"); System.out.println("克隆对象是否相同:"+(weekdayInformation==week2));// //?? 为什么两个都相同了?? 因为指向的同一个对象 System.out.println("被引用对象TestClone是否相同:"+(weekdayInformation.getStrClone()==week2.getStrClone())); //相同? --相同 System.out.println("基本对象String是否相同:"+(weekdayInformation.getStrInformation()==week2.getStrInformation())); //相同? -- 相同 System.out.println("***********\n"); System.out.println(week2.toString()); System.out.println("***********************"); /* * weekdayInformation修改信息 则week2的信息也修改 */ TestClone testClone1=new TestClone(); testClone1.setTestString("test1"); System.out.println("weekdayInformation修改了信息:"); weekdayInformation.setStrTime("周二"); weekdayInformation.setStrClone(testClone1); System.out.println(weekdayInformation.toString()); System.out.println(week2.toString()); System.out.println("***********************"); /* * week2修改信息 则weekdayInformation的信息也修改 */ TestClone testClone2=new TestClone(); testClone2.setTestString("test2"); System.out.println("week2修改了信息:"); week2.setStrTime("周三"); week2.setStrClone(testClone2); System.out.println(weekdayInformation.toString()); System.out.println(week2.toString()); }}/*输出结果如下: 事件:吃饭 时间:周一 地点:食堂 测试:test 浅克隆 克隆信息如下:事件:吃饭 时间:周一 地点:食堂 测试:test 克隆对象是否相同:false 被引用对象TestClone是否相同:true 基本对象String是否相同:true *********** 事件:吃饭 时间:周一 地点:食堂 测试:test *********************** weekdayInformation修改了信息: 事件:吃饭 时间:周二 地点:食堂 测试:test1 事件:吃饭 时间:周一 地点:食堂 测试:test *********************** week2修改了信息: 事件:吃饭 时间:周二 地点:食堂 测试:test1 事件:吃饭 时间:周三 地点:食堂 测试:test2*/
// ———–4、深克隆 里面有被引用对象———-
package ninthTestModel;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import sixTestOop.TestEighthToString;/* * 浅克隆 * 深克隆 * 序列化。 * 区别在于对象有引用对象的时候 一个是指向同一个引用对象 一个是指向不同对象 *//* * * 【浅克隆】,通常只是对克隆的实例进行复制,但里面的其他子对象,都是共用的。 * 【深克隆】,克隆的时候会复制它的子对象的引用,里面所有的变量和子对象都是又额外拷贝了一份。 * */class TestClone{ public String testString; public void setTestString(String testString) { this.testString = testString; } public String getTestString() { return testString; }}// 周报class WeekdayInformation implements Cloneable{ public String strInformation; // 事件 public String strTime; // 时间 public String strLocation; // 地点 public TestClone strClone; // 被引用对象 public String getStrInformation() { return strInformation; } public String getStrTime() { return strTime; } public String getStrLocation() { return strLocation; } public TestClone getStrClone() { return strClone; } public void setStrInformation(String strInformation) { this.strInformation = strInformation; } public void setStrTime(String strTime) { this.strTime = strTime; } public void setStrLocation(String strLocation) { this.strLocation = strLocation; } public void setStrClone(TestClone strClone) { this.strClone = strClone; } // 浅克隆 @Override protected WeekdayInformation clone() throws CloneNotSupportedException { // TODO Auto-generated method stub Object object=null; object=super.clone(); System.out.println("浅克隆"); return (WeekdayInformation) object; } // 深克隆 public WeekdayInformation deepClone() throws IOException, ClassNotFoundException { // -- 将对象写入流中 ByteArrayOutputStream bao=new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bao); oos.writeObject(this); // -- 将对象从流中取出 ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray()); ObjectInputStream ois=new ObjectInputStream(bis); return (WeekdayInformation) ois.readObject(); } @Override public String toString() { // TODO Auto-generated method stub return "事件:"+strInformation+"\t时间:"+strTime+"\t地点:"+strLocation+"\t测试:"+strClone.getTestString(); }}public class CloneModel { public static void main(String[] args) throws CloneNotSupportedException { // TODO Auto-generated method stub WeekdayInformation weekdayInformation=new WeekdayInformation(); TestClone testClone=new TestClone(); testClone.setTestString("test"); weekdayInformation.setStrInformation("吃饭"); weekdayInformation.setStrTime("周一"); weekdayInformation.setStrLocation("食堂"); weekdayInformation.setStrClone(testClone); System.out.println(weekdayInformation.toString()); // 如果没有重写toString()方法会显示:ninthTestModel.WeekdayInformation@2a139a55 WeekdayInformation week2=weekdayInformation.deepClone();// 这里调用深克隆实现 System.out.println("被引用对象是否相同:"+(weekdayInformation.getStrClone()==week2.getStrClone())); //相同? 不同 System.out.println("是否相同:"+(weekdayInformation.getStrInformation()==week2.getStrInformation())); //相同? 不同 System.out.println(week2.toString()); System.out.println("***********************"); /* * weekdayInformation修改信息 则week2的信息也修改 */ TestClone testClone1=new TestClone(); testClone1.setTestString("test1"); System.out.println("weekdayInformation修改了信息:"); weekdayInformation.setStrTime("周二"); weekdayInformation.setStrClone(testClone1); System.out.println(weekdayInformation.toString()); System.out.println(week2.toString()); System.out.println("***********************"); /* * week2修改信息 则weekdayInformation的信息也修改 */ TestClone testClone2=new TestClone(); testClone2.setTestString("test2"); System.out.println("week2修改了信息:"); week2.setStrTime("周三"); week2.setStrClone(testClone2); System.out.println(weekdayInformation.toString()); System.out.println(week2.toString()); }}/* 输出结果如下: 事件:吃饭 时间:周一 地点:食堂 测试:test 浅克隆 克隆信息如下:事件:吃饭 时间:周一 地点:食堂 测试:test 克隆对象是否相同:false 被引用对象TestClone是否相同:true 基本对象String是否相同:true *********** 事件:吃饭 时间:周一 地点:食堂 测试:test *********************** weekdayInformation修改了信息: 事件:吃饭 时间:周二 地点:食堂 测试:test1 事件:吃饭 时间:周一 地点:食堂 测试:test *********************** week2修改了信息: 事件:吃饭 时间:周二 地点:食堂 测试:test1 事件:吃饭 时间:周三 地点:食堂 测试:test2*/
自我理解:
对象一 对象二=对象一的复制/浅克隆/深克隆
复制:对象一=对象二 二者完全值得同一个 如果对象一修改 对象二则跟着修改
浅克隆:对象一、二不同,但是对于被引用对象指向的会是同一个对象,
深克隆:对象一、二不同,是完全的创建出了一个新的对象,
对于被引用对象也不同,如这里我所用到的引用对象testClone。
问题:
但是有个问题我没搞懂,浅克隆的时候为什么String类型的对象也指向的同一个?
也就是在例子三中
被引用对象TestClone是否相同:true //–这个应该是true
基本对象String是否相同:true //– 这个不应该是false嘛?怎么回事true
源码:
System.out.println("被引用对象TestClone是否相同:"+(weekdayInformation.getStrClone()==week2.getStrClone())); //相同?System.out.println("基本对象String是否相同:"+(weekdayInformation.getStrInformation()==week2.getStrInformation())); //相同?
– 以上如果有错,欢迎指出。
0 0
- 浅克隆、深克隆
- 深克隆,浅克隆
- 浅克隆和深克隆
- 深克隆与浅克隆
- 深克隆与浅克隆
- Java深克隆浅克隆
- 深克隆 与 浅克隆
- 深克隆与浅克隆
- 深克隆与浅克隆
- 深克隆与浅克隆
- 深克隆和浅克隆
- 深克隆和浅克隆
- 浅克隆与深克隆
- 深克隆和浅克隆
- 深克隆和浅克隆
- 深克隆和浅克隆
- 浅克隆和深克隆
- 浅克隆和深克隆
- JAVA面试题04-HashMap的实现
- Python3 cookbook学习笔记-数据结构与算法4
- BZOJ4236: JOIOJI
- 《剑指offer》
- 数据库系统原理笔记1
- 浅克隆、深克隆
- Web安全工程师长成技能表
- 虚拟化和应用交付的珠联璧合
- html类名允许重复吗
- 事件对象
- 03-树1 树的同构 (25分)
- 蓝桥杯 算法训练 单词接龙 By Assassin [搜索水题]
- 打印100~200 之间的素数
- javascript基本语法(一)