资讯专栏INFORMATION COLUMN

Java Clone

dabai / 1310人阅读

摘要:类自带了本地的方法,该方法会返回现有实例的副本。如果要使用克隆,必须实现接口,以便它不会在运行时抛出。如果函数会返回对象副本,那么在什么情况下我们需要重写它让我们运行下面的类来更好的理解。

Java类自带了本地的clone()方法,该方法会返回现有实例的副本。如果要使用Java克隆,必须实现java.lang.Cloneable接口,以便它不会在运行时抛出CloneNotSupportedException。
如果clone()函数会返回对象副本,那么在什么情况下我们需要重写它?
让我们运行下面的java类来更好的理解。

import java.util.HashMap;
import java.util.Iterator;

/**
 * @author 三产
 * @version 1.0
 * @date 2017-03-21
 * @QQGroup 213732117
 * @website http://www.coderknock.com
 * @copyright Copyright 2017 拿客 coderknock.com  All rights reserved.
 * @since JDK 1.8
 */
public class Clone implements Cloneable {
    private int id;

    private String name;

    private HashMap props;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public HashMap getProps() {
        return props;
    }

    public void setProps(HashMap props) {
        this.props = props;
    }
   
    public static void main(String[] args) throws CloneNotSupportedException {
        Clone ct1 = new Clone();
        ct1.setId(1);
        ct1.setName("first");
        HashMap hm = new HashMap();
        hm.put("1", "first");
        hm.put("2", "second");
        hm.put("3", "third");
        ct1.setProps(hm);
        // Using default clone() implementation
        Clone ct2 = (Clone) ct1.clone();
        // Check whether the ct1 and ct2 attributes are same or different
        System.out.println("ct1 and ct2 HashMap == test: "
                + (ct1.getProps() == ct2.getProps()));
        // Lets see the effect of using default cloning
        ct1.getProps().put("4", "fourth");
        System.out.println("ct1 props:" + ct2.getProps());
        System.out.println("ct2 props:" + ct1.getProps());
        ct1.setName("new");
        System.out.println("ct1 name:" + ct1.getName());
        System.out.println("ct2 name:" + ct2.getName());
    }
}

输出如下:

ct1 and ct2 HashMap == test: true
ct1 props:{1=first, 2=second, 3=third, 4=fourth}
ct2 props:{1=first, 2=second, 3=third, 4=fourth}
ct1 name:new
ct2 name:first 

很明显,默认clone()函数使用的是浅复制的副本,ct2受ct1属性中的任何更改的影响,所以我们需要覆盖clone方法,这时我们反馈clone的注解。
在上面的类中添加下面代码:

  public Clone clone() {
        System.out.println("invoking overridden clone method");
        HashMap hm = new HashMap<>();
        String key;
        Iterator it = this.props.keySet().iterator();
        // 深复制属性
        while (it.hasNext()) {
            key = it.next();
            hm.put(key, this.props.get(key));
        }
        Clone ct = new Clone();
        ct.setId(this.id);
        ct.setName(this.name);
        ct.setProps(hm);
        return ct;
    }

再次运行:

ct1 and ct2 HashMap == test: false
ct1 props:{1=first, 2=second, 3=third}
ct2 props:{1=first, 2=second, 3=third, 4=fourth}
ct1 name:new
ct2 name:first

这时,我们就可以发现深复制与浅复制的区别了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66865.html

相关文章

  • clone方法到复制构造函数

    摘要:有一些设计缺陷,其中最大的一个是接口没有方法。这基本上就是你用复制构造函数做的事情。复制构造方法有几个优点,我在本书中有讨论。的方法是非常棘手的。它创建一个对象而不调用构造函数。无法保证它保留构造函数建立的不变量。 前言 在Java API中,可以通过实现Cloneable接口并重写clone方法实现克隆,但Java设计者否定了使用clone创建新对象的方法. 1. clone方法实现...

    孙吉亮 评论0 收藏0
  • Java 作者谈克隆方法的实现

    摘要:不合规的代码示例合规解决方案参阅复制构造函数与克隆也可以参阅应该实现克隆覆盖的类应为并调用下面为引文翻译谈设计与作者的对话,作者首次在上发表,年月日复制构造函数与克隆在你的书中,你建议使用复制构造函数而不是实现和编写。 今天在用 sonar 审核代码, 偶然看到下面的提示:showImg(https://segmentfault.com/img/bVbqioZ?w=858&h=116)...

    gaomysion 评论0 收藏0
  • Java进阶2 —— 使用Object的通用方法

    摘要:判断另外一个对象是否与当前对象相等返回当前对象的哈希值返回一个表示当前对象的字符串唤醒一个等待当前对象的锁监视器的线程。 原文链接:http://www.javacodegeeks.com/2015/09/using-methods-common-to-all-objects.html 本文是Java进阶课程的第二篇。 本课程的目标是帮你更有效的使用Java。其中讨论了一些高级主题,包...

    jzman 评论0 收藏0
  • #yyds干货盘点#Java设计模式之(四)——原型模式

    摘要:如果一个对象的初始化需要很多其他对象的数据准备或其他资源的繁琐计算,那么可以使用原型模式。当需要一个对象的大量公共信息,少量字段进行个性化设置的时候,也可以使用原型模式拷贝出现有对象的副本进行加工处理。 1、什么是原型模式Specify the kinds of objects to create using a prot...

    番茄西红柿 评论0 收藏2637

发表评论

0条评论

最新活动
阅读需要支付1元查看
<