原型模式(克隆模式)

对象A指向的是它的内存地址,当我们把对象A赋值给对象B,他俩还是指向的同一处地址,修改A的话,B也跟着变了。(基本数据类型则是直接赋值,String类型虽然是引用类型,但它被final修饰不可改变的,所以你修改它时其实修改的是string的另一个新的指向引用,所以String自带深克隆)对象的重默认clone()方法会调用super.clone(),其实是浅拷贝。

School学校类,给User充当引用类型变量

public class School {
  private String name;

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

    public String getName() {
        return name;
    }

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

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

User类,有自带深克隆的String变量和引用类型的School变量

public class User implements Cloneable{
    private String name;
    private School school;

    public User(String name, School school) {
        this.name = name;
        this.school = school;
    }

    public String getName() {
        return name;
    }

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

    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }

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

浅克隆就是直接调用clone()方法,赋值不彻底,基本数据类型不会影响, 但是引用类型影响克隆出来的副本

    public static void main(String[] args) throws CloneNotSupportedException {
        User user=new User("张三",new School("小学"));
        User userClone= (User) user.clone();
        userClone.setName("李四");
        userClone.getSchool().setName("大学");
        System.out.println(user+" "+userClone);//User{name='张三', school=School{name='大学'}} User{name='李四', school=School{name='大学'}}
    }

因为他们的school都是指向同一块地址,自然会跟着改变。
深克隆就是彻底克隆一个副本出来,互不影响。目的在于如何实现深克隆

实现深克隆

User类实现Cloneable接口,并重写clone()方法,

  @Override
    protected Object clone() throws CloneNotSupportedException {
        User user= (User) super.clone();//clone()默认是浅拷贝,所以我们先把浅拷贝的基本数据类型,String拷贝一下
//        再格外处理一下引用类型
        user.setSchool((School) user.getSchool().clone());
        return user;
    }

这样就实现了深度拷贝(如果School里面也有引用类型的话,同理去重写clone()方法就行了,直到你的引用类型里只剩下基本数据类型或者String
等)

序列化实现深拷贝

重写Clone方法可太复杂了。复杂点的对象直接俄罗斯套娃。推荐使用序列化
Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。

将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象。

原理就是将对象放入别的地方,取过来时直接给他开辟一个新内存地址,自然实现深度拷贝
对象需要实现Serializable接口,然后利用ObjectOutputStream/ObjectInputStream进行中转即可

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值