浅克隆、深克隆

来源:互联网 发布:用二分法求根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
原创粉丝点击