原型模式 浅克隆 深克隆

为什么需要克隆:因为实例(对象)是引用传递,不管赋值多少个 都是一个

package prototype.prototype2;

public class Prototype {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student("晓峰",21);
        Student student2 = student1;
        System.out.println(student1);
        System.out.println(student2);
        student1.setName("晓畅");
        System.out.println(student1);
        System.out.println(student2);
        /**
         * Student{name='晓峰', age=21}
         * Student{name='晓峰', age=21}
         * Student{name='晓畅', age=21}
         * Student{name='晓畅', age=21}
         */
    }
}


class Student{
    private String name;
    private int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;

    }
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

内存示意图:

 修改了sutdnet1中的name student2 的也会改变 ,因为student1和student2 指向的内存空间是一块

我们想要的是student1和student2 分别指向的两块内存 ,所以就出现了克隆

先说下java如何实现克隆:

1.实现 Cloneable接口,并重写clone方法

class Student implements Cloneable{
    ...
    public Object clone() throws CloneNotSupportedException {
        return  super.clone();
    }
}

2.自己写clone

class Student{
    ...
    public Object clone(){
        Schoolbag schoolbagclone = new Schoolbag(this.schoolbag.getSize(),this.schoolbag.getColor());
        Student studentclone = new Student(this.name,this.age,schoolbagclone);

        return studentclone;
    }
}

克隆操作的代码:

package prototype.prototype2;

public class Prototype {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student("晓峰",21);
        Student student2 = student1.clone();
        System.out.println(student1);
        System.out.println(student2);
        student1.setName("晓畅");
        System.out.println(student1);
        System.out.println(student2);
        /**
         * Student{name='晓峰', age=21}
         * Student{name='晓峰', age=21}
         * Student{name='晓畅', age=21}
         * Student{name='晓峰', age=21}
         */
    }
}


class Student{
    private String name;
    private int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;

    }
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Student clone() {
        Student studentclone = new Student(this.name, this.age);
        return studentclone;
    }

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

内存示意图:

这就是克隆的方式了,不过还存在一个问题,就是套娃,如果一个类中的属性存在非简单值类型,就要小心了,就要实现深拷贝

package prototype.prototype1;

public class Prototype {
    public static void main(String[] args) throws CloneNotSupportedException {
        Schoolbag schoolbag = new Schoolbag("大","红色");
        Student student = new Student("晓峰",13,schoolbag);
        Student student1 = (Student)student.clone();
        student.setAge(23);
        student.getSchoolbag().setColor("蓝色");
        System.out.println(student);
        System.out.println(student1);
    }
}


class Student{
    private String name;
    private int age;
    private Schoolbag schoolbag;

    public Student(String name, int age, Schoolbag schoolbag) {
        this.name = name;
        this.age = age;
        this.schoolbag = schoolbag;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Schoolbag getSchoolbag() {
        return schoolbag;
    }

    public void setSchoolbag(Schoolbag schoolbag) {
        this.schoolbag = schoolbag;
    }

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

    public Object clone(){
        Schoolbag schoolbagclone = new Schoolbag(this.schoolbag.getSize(),this.schoolbag.getColor());
        Student studentclone = new Student(this.name,this.age,schoolbagclone);

        return studentclone;
    }
}

class Schoolbag{
    private String size;//l xl xxl
    private String color;

    public Schoolbag(String size, String color) {
        this.size = size;
        this.color = color;
    }

    public String getSize() {
        return size;
    }

    public void setSize(String size) {
        this.size = size;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "Schoolbag{" +
                "size='" + size + '\'' +
                ", color='" + color + '\'' +
                '}';
    }

    public Object clone(){
        Schoolbag schoolbagclone = new Schoolbag(this.size,this.color);
        return schoolbagclone;
    }
}

内存示意图就不画了自己脑补吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值