Java -- 浅克隆和深克隆定义和实现

Posted Z && Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java -- 浅克隆和深克隆定义和实现相关的知识,希望对你有一定的参考价值。

1. 浅克隆的定义

在浅克隆中,如果原型对象的成员变量是基本数据类型(int,double…),将复制一份给克隆对象,如果是引用类型,则直接将引用对象的地址复制一份给克隆对象。


2. 深克隆的定义

无论原型对象的成员变量是基本数据类型还是引用类型,都会直接复制一份给克隆对象


3. 浅克隆的实现

Object类有个clone()的拷贝方法,不过它是protected类型的,我们需要重写它并修改为public类型。除此之外,子类还需要实现Cloneable接口来告诉JVM这个类是可以拷贝的。

让我们修改一下Student类,实现Cloneable接口,使其支持拷贝。

Student.java

public class Student implements Cloneable {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
	
	// 重写克隆方法
    @Override
    public Student clone() throws CloneNotSupportedException {
        return (Student) super.clone();
    }
}

测试:

    @org.junit.Test
    public void coneableCopy() throws CloneNotSupportedException {
//         被克隆的类
        Student xiaoMing = new Student("小明");
        Student cloneStudent = xiaoMing.clone();
        System.out.println(xiaoMing == cloneStudent);
    }


4. 深克隆的实现

案例:

用原型模式生成"三好学生"奖状

需求:

同一学校的"三好学生"奖状除了获奖人姓名不同,其他都相同,可以使用原型模式复制多个"三好学生"奖状出来,然后在修改奖状上的名字即可。


4.1 学生类

package com.tian.pattern.prototype.test;

/**
 * 学生类
 */
public class Student {

    //学生的姓名
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\\'' +
                '}';
    }
}

4.2 奖状类

package com.tian.pattern.prototype.test;

/**
 * 奖状类
 */
public class Citation implements Cloneable {
    private Student stu;

    public Student getStu() {
        return stu;
    }

    public void setStu(Student stu) {
        this.stu = stu;
    }

    @Override
    public Citation clone() throws CloneNotSupportedException {
        return (Citation) super.clone();
    }

    public void show() {
        System.out.println(stu.getName() + "同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }
}

4.3 测试类

package com.tian.pattern.prototype.test;

/**
 * 测试类
 */
public class CitaionTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        //1,创建原型对象
        Citation citation = new Citation();
        //创建张三学生对象
        Student stu = new Student();
        stu.setName("张三");
        citation.setStu(stu);

        //2,克隆奖状对象
        Citation citation1 = citation.clone();
        Student stu1 = citation1.getStu();
        stu1.setName("李四");

        System.out.println(stu == stu1 ? "stu和stu1是同一个对象" : "stu和stu1不是同一个对象");
        //3,调用show方法展示
        citation.show();
        citation1.show();
    }
}

4.4 运行结果


4.5 说明


4.6 深克隆 – 学生类

package com.tian.pattern.prototype.test1;

import java.io.Serializable;

/**
 * 学生类
 */
public class Student implements Serializable {

    //学生的姓名
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\\'' +
                '}';
    }
}

4.7 深克隆 – 奖状类

package com.tian.pattern.prototype.test1;

import java.io.Serializable;

/**
 * 奖状类
 */
public class Citation implements Cloneable, Serializable {
    private Student stu;

    public Student getStu() {
        return stu;
    }

    public void setStu(Student stu) {
        this.stu = stu;
    }

    @Override
    public Citation clone() throws CloneNotSupportedException {
        return (Citation) super.clone();
    }

    public void show() {
        System.out.println(stu.getName() + "同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }
}

4.8 深克隆 – 测试类

package com.tian.pattern.prototype.test1;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 测试类
 */
public class CitaionTest {
    public static void main(String[] args) throws Exception {
        //1,创建原型对象
        Citation citation = new Citation();
        //创建张三学生对象
        Student stu = new Student();
        stu.setName("张三");
        citation.setStu(stu);

        //创建对象输出流对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\\\IDEACode\\\\workspace\\\\heima-design-patterns\\\\src\\\\main\\\\resources\\\\object.txt"));
        //写对象
        oos.writeObject(citation);
        //释放资源
        oos.close();

        //创建对象输入流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\\\IDEACode\\\\workspace\\\\heima-design-patterns\\\\src\\\\main\\\\resources\\\\object.txt"));
        //读取对象
        Citation citation1 = (Citation) ois.readObject();
        //释放资源
        ois.close();
        Student stu1 = citation1.getStu();
        stu1.setName("李四");
        
        System.out.println(stu == stu1 ? "stu和stu1是同一个对象" : "stu和stu1不是同一个对象");
        citation.show();
        citation1.show();
    }
}

4.9 深克隆 – 运行结果



以上是关于Java -- 浅克隆和深克隆定义和实现的主要内容,如果未能解决你的问题,请参考以下文章

克隆_浅拷贝和深拷贝

java对象的浅克隆和深克隆

Java浅克隆和深克隆

Java中的浅克隆和深克隆

Java学习笔记——设计模式之六.原型模式(浅克隆和深克隆)

分别给出浅克隆和深克隆实现