• Java Clone


    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<String, String> 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<String, String> hm = new HashMap<>();
            String key;
            Iterator<String> 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

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

  • 相关阅读:
    Open vSwitch使用案例扩展实验
    hdoj-1233-还是畅通工程
    DS实验题 Floyd最短路径 & Prim最小生成树
    DS实验题 Missile
    Mininet实验 基于Mininet实现BGP路径挟持攻击实验
    Gift for GS5
    Bellman-Ford算法
    pox目录中的交换机mac地址学习模块 l2_multi源码
    Mininet实验 使用l2_multi模块寻找最短路径实验
    Ubuntu安装Flash
  • 原文地址:https://www.cnblogs.com/twodog/p/12140985.html
Copyright © 2020-2023  润新知