Java原型模式详解:克隆人案例【深浅克隆】

这篇具有很好参考价值的文章主要介绍了Java原型模式详解:克隆人案例【深浅克隆】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言
在许多情况下,我们需要创建对象的副本,比如在初始化操作比较复杂或者需要大量资源的情况下。在这些情况下,我们可以使用原型模式来避免重复创建对象,提高程序的性能。本文将介绍Java中的原型模式以及如何在实际应用中使用它。

一、原型模式概述

原型模式(Prototype Pattern)属于创建型设计模式,它的核心思想是通过克隆一个已经存在的对象(原型)来返回新的对象,而不是通过实例化类来创建新的对象。关于对象克隆,在Object类中已经提供了相应的方法clone(),我们只需要调用即可。这种方式在某些场景下,能够大大提高对象创建的效率。

1.1 如何实现?

Java中的原型模式实现很简单,只需要在需要被复制的对象上实现Cloneable接口,并且重写Object中的clone方法即可。

Cloneable接口是 Java 中的一个标记接口,它没有任何方法,只是作为一个标识,告诉编译器该类可以被克隆。当一个类实现了 Cloneable接口并重写了 Object类中的clone方法,就可以通过clone方法创建一个该类的实例的副本,也就是克隆对象。

注意事项

  • 只有实现了 Cloneable 接口的类才能够被克隆,否则会抛出 CloneNotSupportedException 异常。
  • Object类中的 clone方法是protected类型,并不能直接被其他类调用,需要在子类中重写 clone方法进行公开。
  • 原生clone方法是浅拷贝。关于深浅拷贝的区别看后文图解说明。

1.2 优缺点

优点

  • 可以避免重复创建对象,减少对象创建开销,提高程序性能。
  • 简化对象的创建过程,隐藏对象的创建细节。
  • clone方法基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。

缺点

  • 在使用原型模式时,需要注意对成员变量中引用类型的处理,以避免浅拷贝带来的问题。
  • 在需要深拷贝的情况下,实现起来比较复杂,特别是在对象的层次结构很深的情况下,需要各层级递归处理。

1.3 适用场景

原型模式在以下几种情况下比较适用:

  • 当一个对象的创建过程非常复杂或者耗时时,可以通过复制一个已经创建好的实例来获得新的实例,从而提高性能。
  • 当一个类的实例之间相互独立(状态不共享),且具有相同的结构时,可以使用原型模式简化创建过程。
  • 当需要大量相同或相似对象时,使用原型模式避免重复创建对象。

1.4 Java Api中的原型案例

在Java API中,有很多类都使用了原型模式,以下是一些示例:

  1. java.util.Date类
  2. java.util.Calendar类
  3. java.util.ArrayList类和java.util.LinkedList类
  4. java.awt.geom.Area类

二、克隆人案例

接下来,我们通过一个克隆人的例子来看看如何在Java中实现原型模式,以及深克隆要如何实现

2.1 浅克隆实现

我们首先创建克隆人模型ClonePeople类,它拥有基本类型属性姓名、年龄,以及引用类型属性:身份证IdentityCard。在ClonePeople类中需要实现Cloneable接口并重写clone方法。

ClonePeople.java

public class ClonePeople implements Cloneable{
    private String name;
    private int age;
    //表示身份证的子对象
    private IdentityCard idCard;

    public ClonePeople(String name, int age, IdentityCard idCard) {
        this.name = name;
        this.age = age;
        this.idCard = idCard;
    }

    public void setIdCard(IdentityCard idCard) {
        this.idCard = idCard;
    }

    public IdentityCard getIdCard() {
        return idCard;
    }

    @Override
    public String toString() {
        return "我是克隆人[" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", idCard=" + idCard.getIdentityId() +
                ']';
    }

    @Override
    public Object clone() {
        ClonePeople clone = null;
        try {
            clone = (ClonePeople)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }
}

IdentityCard.java

public class IdentityCard{
    private String identityId;//证件号

    public String getIdentityId() {
        return identityId;
    }

    public IdentityCard(String identityId) {
        this.identityId = identityId;

    }
}

测试浅克隆后对象和源对象关系

public class Client {
    public static void main(String[] args) {
        //创建原型对象ClonePeople
        IdentityCard idcard=new IdentityCard("1234567890");
        ClonePeople people=new ClonePeople("KangKang",12,idcard);
        //克隆
        ClonePeople anotherPeople = (ClonePeople)people.clone();
        System.out.println(anotherPeople.toString());
        //判断克隆对象地址是否相等
        System.out.println("克隆对象是否相等:"+ (people==anotherPeople));
        //判断子对象地址是否相等
        System.out.println("子对象是否相等:"+(people.getIdCard()==anotherPeople.getIdCard()));
    }
}

测试结果:

Java原型模式详解:克隆人案例【深浅克隆】

结论

根据测试结果可以得出:
1,克隆后的对象是一个新对象,其对象地址不一致,但是内容完全一致,这就是原型模式的魅力。
2,Object中的clone方法正是浅克隆,因为其子对象引用是同一个对象,内存地址是一致的。

2.2 深克隆实现

深克隆就是完全克隆,让子对象也重新创建,而不是引用同一个对象。这要如何实现呢?既然调用clone方法,可以让外部的对象重新创建,那我是不是也可以对子对象也调用clone方法呢。

步骤1:改造子对象,让子对象也实现Cloneable接口并重写clone方法

public class IdentityCard implements Cloneable{
    private String identityId;//证件号

    public String getIdentityId() {
        return identityId;
    }

    public IdentityCard(String identityId) {
        this.identityId = identityId;

    }

    @Override
    public Object clone() {
        IdentityCard clone = null;
        try {
            clone = (IdentityCard)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }
}

步骤2:改造ClonePeople类中的clone方法,对子对象克隆后重新赋值

    @Override
    public Object clone() {
        ClonePeople clone = null;
        try {
            clone = (ClonePeople)super.clone();
            clone.setIdCard((IdentityCard)clone.getIdCard().clone());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }

测试类不变,看测试结果。子对象是否相等为false,这说明子对象也重新创建了,而不是引用之前的对象。

Java原型模式详解:克隆人案例【深浅克隆】

结论

如果要实现深拷贝,不仅对象要重写clone方法,其各级子对象也要依次重写clone方法,而且需要对子对象重新设值,各层级递归处理,颇为麻烦。具体是否需要进行深拷贝,那就因地制宜了,视业务场景而定。

三、Java浅拷贝VS深拷贝

一个对象中属性类型可以分为基本数据类型和引用数据类型(或称子对象、属性对象),深浅拷贝的区别就在于子对象的拷贝上。

  • 浅拷贝:对于对象中的引用类型,只拷贝其引用,新的引用仍然指向原来的子对象。

  • 深拷贝:完全拷贝,对引用类型也开辟新的内存空间。

Java原型模式详解:克隆人案例【深浅克隆】

四、总结

经过上面的讲解,相信大家对Java原型模式有了更深入的了解。原型模式通过复制已有实例来创建新的实例,可以在一定程度上提高对象创建的效率。同时,原型模式适用于对象创建过程复杂、实例之间状态不共享且具有相同结构的场景。

在实际开发中,我们可以根据项目需求灵活运用原型模式,优化代码结构,提高代码的可读性和可维护性。当然,原型模式并不是万能的,我们还需要结合其他设计模式来解决实际问题。

希望本文能够帮助大家更好地理解和掌握原型模式。如果你觉得本文对你有所帮助,请不要吝啬你的点赞和分享,让更多的人受益!同时,欢迎大家在评论区留言交流,我们共同学习,共同进步!


Java原型模式详解:克隆人案例【深浅克隆】文章来源地址https://www.toymoban.com/news/detail-451270.html

到了这里,关于Java原型模式详解:克隆人案例【深浅克隆】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 原型模式-克隆一个对象

     在开发一个界面的时候,里面有多个Button,这些对象的属性内容相似。如果一个个实例化Button对象,并设置其属性,那么代码量将会增多。 通过一个原型对象克隆出多个一模一样的对象,该模式被称为原型模式。  图 原型模式 Prototype: 抽象原型类,是声名克隆方法的接口,

    2024年02月16日
    浏览(40)
  • Java设计模式之创建型-原型模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析  4.1、通用实现(浅克隆) 4.2、深克隆 五、总结 原型模式通过复制已有对象作为原型,通过复制该原型来返回一个新对象,而不是新建对象,说白了就是不断复制相同的对象罢了。 角色 描述 抽象原型类 规定了具

    2024年02月15日
    浏览(49)
  • 【设计模式——学习笔记】23种设计模式——原型模式Prototype(原理讲解+应用场景介绍+案例介绍+Java代码实现)

    原型模式指用通过拷贝原型实例创建新的实例,新实例和原型实例的属性完全一致 原型模式是一种创建型设计模式 工作原理是通过调用原型实例的 clone() 方法来完成克隆,原型实例需要实现Cloneable接口,并重写 clone() 方法 需要为每个类开发一个克隆方法,这对全新的类来说

    2024年02月16日
    浏览(52)
  • 【原型设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    原型模式(Prototype Pattern)是一种创建型设计模式,使你能够复制已有对象,而无需使代码依赖它们所属的类,同时又能保证性能。 这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。 如果你需要复制一些对

    2023年04月24日
    浏览(84)
  • 〖大前端 - 基础入门三大核心之JS篇㊿〗- 面向对象之对象的方法、遍历、深浅克隆

    说明:该文属于 大前端全栈架构白宝书专栏, 目前阶段免费 , 如需要项目实战或者是体系化资源,文末名片加V! 作者:哈哥撩编程,十余年工作经验, 从事过全栈研发、产品经理等工作,目前在公司担任研发部门CTO。 荣誉: 2022年度博客之星Top4、2023年度超级个体得主、谷

    2024年02月04日
    浏览(75)
  • 设计模式-原型模式详解

    简介设计模式 设计模式是在软件开发中常见问题的解决方案,它们是经过实践和经验总结出来的可重用的设计思想和解决方案。设计模式通过提供通用的架构、原则和指导,帮助开发人员更有效地编写高质量的代码。 设计模式分为三个主要类别: 创建型模式:关注对象的创

    2024年02月10日
    浏览(36)
  • 设计模式之原型模式详解

    在设计模式的系列文章中,我们前面已经写了 工厂模式 、 单列模式 、 建造者模式 ,在针对创建型模式中,今天想跟大家分享的是 原型模式 ,我觉的这种模式叫克隆模式会更佳恰当。原型模式的目的就是通过复制一个现有的对象来生成一个新的对象。 原型模式 使用原型实

    2024年02月12日
    浏览(42)
  • c#中原型模式详解

    基础介绍:    具体可分为2个角色:     Prototype(原型类):声明一个Clone自身的接口;     ConcretePrototype(具体原型类):,实现一个Clone自身的操作。 在原型模式中,Prototype通常提供一个包含Clone方法的接口,具体的原型ConcretePrototype使用Clone方法完成对象的创

    2024年02月05日
    浏览(41)
  • Java设计模式-原型模式

    原型模式是一种创建型设计模式,它允许在运行时通过复制现有对象来创建新对象,而不是通过构造函数创建。这个模式的核心思想是基于一个现有的对象克隆一个新的对象,这个过程对外部世界是透明的,就像对象从未被克隆过一样。 原型模式的一个关键优点是可以避免在

    2024年02月03日
    浏览(48)
  • Java设计模式之原型模式

            原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式之一。         这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大

    2024年02月10日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包