Java设计模式-原型模式(Prototype)

原型模式介绍

  • 这种类型的设计模式属于创建型模式,用于创建重复的对象。
  • 原型模式也就是克隆模式(通俗的来说,就是我们电脑上的复制,粘贴的操作,两个文件的内容是一模一样的,但两个都是独立的文件,无不影响。)
  • JAVA中就替我们实现了原型模式。(java.lang.Cloneable中的clone()方法)
  • 需要实现标记性接口Cloneable,重写clone()方法
  • 需要区分浅克隆和深克隆
    在这里插入图片描述

1.浅克隆

  • 想要实现一个类的克隆,就要实现Cloneable接口,重写Object的clone方法
class Person implements Cloneable{
    String name;
    int age;
    
    public Object clone() throws CloneNotSupportedException {
        return super.clone();

    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Test001 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person("Jungwon",22);
        System.out.println(person);
        System.out.println(person.hashCode());
        Person person1 = (Person) person.clone();
        System.out.println(person1);
        System.out.println(person1.hashCode());
    }
}


从结果我们可以看到person1是person克隆出来的对象,两个对象属性值相同,hashcode不同。

2.深克隆

2.1 为什么需要深克隆

当我们的类里的属性不仅有基本数据类型,还有引用类型时

class Person implements Cloneable{
    String name;
    int age;
    Location location = new Location();
}

这时我们上面的克隆方式能否也能将类里的引用类型克隆出来?

public static void main(String[] args) throws CloneNotSupportedException {//测试
        Person person = new Person("Jungwon",22);
        System.out.println(person.location.hashCode());
        Person person1 = (Person) person.clone();
        System.out.println(person1.location.hashCode());
    }

在这里插入图片描述
结果很明显是不能的,这时我们就需要使用到深克隆了。

2.2 深克隆的代码实现

  • 实现原理很简单,引用类也实现Cloneable接口,重写clone方法
  • Location类实现Cloneable接口,重写clone方法.
  • 改写Person类里的clone()。
class Person implements Cloneable{
    String name;
    int age;
    Location location = new Location("changchun");

    public Object clone() throws CloneNotSupportedException {
        Person person = (Person)super.clone();
        person.location = (Location) location.clone();
        return person;

    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
  
}

class Location implements Cloneable{
    String loc;

    public Location(String loc) {
        this.loc = loc;
    }
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

测试

 public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person("Jungwon",22);
        System.out.println(person.location.hashCode());
        Person person1 = (Person) person.clone();
        System.out.println(person1.location.hashCode());
    }

在这里插入图片描述
这时类中的引用类型也克隆出来了。

2.3 小疑点

这时有人会问String类型不也是引用类型吗?String也要深克隆吗?

String类型不需要进行深克隆。
因为String类型直接指定常量池,所以他本来是一个共用的。
我们都知道String是一个final修饰的,是个不可变的变量。当改变String = “abc"值为"bcd"时,其实会生成一个新的String对象值为"bcd”,所以当我们修改被克隆对象值或克隆对象值,都不会影响另一个。

3.小结

原型模式中最重要的是区分浅克隆和深克隆

3.1浅克隆和深克隆的区分

  • 浅克隆: 创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

  • 深克隆: 创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

总之深浅克隆都会在堆中新分配一块区域,区别在于对象属性引用的对象是否需要进行克隆(递归性的)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值