浅克隆、深克隆

// ———-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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值