zoukankan      html  css  js  c++  java
  • EffectiveJava(11)Java中的clone

    java中的clone

    clone构造器及其静态工厂的变形
    优点:它们不依赖于某一种很有风险的,语言之外的对象创建机制;
    它们不要求遵守尚未制定好文档的规范
    他们不会于final域的正常使用发生冲突
    它们不会抛出不必要的受检异常
    它们不需要进行类型转换

    /**
    * 1.必须继承Cloneable接口
    * 2.必须重写Object类中的clone()方法 –
    * Cloneable接口改变了接口的通用规范,它改变了超类中受保护的方法的行为
    * –无需构造器就可以创建对象
    * a.clone对象分配有独立的内存地址 – x.clone()!=x;
    * b.原始的克隆对象应该具有相同类型 x.clone().getClass == x.getClass 非必需
    * c.原始的克隆对象调用equals方法的话,应该是相等的 非必需
    * @author JacXuan
    *
    */

    public class Father implements Cloneable{
        private int age;
        private String name;
        private Son son;
    
        public Father(int age,String name,Son son){
            this.age = age;
            this.name = name;
            this.son = son;
        }
    
        public Son getSon(){
            return this.son;
        }
        public void setSon(Son son){
            this.son = son;
        }
        /**
         * 浅拷贝代码--
         * 原始对象和克隆对象拥有指向同一对象的两个引用,所以可以通过改变cloneFather
         * 中的Son来改变father中的Son对象
         * @throws CloneNotSupportedException 
         */
    //  @Override
    //  public Object clone() throws CloneNotSupportedException{
    //      return super.clone();
    //  }   
    
        /**
         * 深拷贝 -- 在Son中实现clone方法  return super.clone();
         */
        @Override
        public Object clone() throws CloneNotSupportedException{
            Father father = (Father)super.clone();
            father.setSon((Son)father.getSon().clone());
            return father;
        }
    }
    
    
        Son son  = new Son(20, "PG");
            Father father = new Father(40, "JacX", son);
    
                Father cloneFather = (Father)father.clone();
                System.out.println(father!=cloneFather);
                System.out.println(cloneFather.getClass() == father.getClass());
                System.out.println(cloneFather.equals(father));
    
    
    2.package com.object.equals.clone.conctr;
    
    /**
     * 拷贝构造函数 -- 一种特殊的构造器
     * 它将自己的类类型作为参数  传递一个类的实例给拷贝构造函数,
     * 然后他将返回一个新的类实例
     * @author JacXuan
     *
     */
    public class CloneConctr {
        private Integer x;
        private  Integer y;
    
        public CloneConctr(CloneConctr cloneConctr){
            this.x = cloneConctr.x;
            this.y=cloneConctr.y;
        }
    
    //  public CloneConctr copyPoint(CloneConctr cloneConctr) throws CloneNotSupportedException{
    //      if(!(cloneConctr instanceof Cloneable)){
    //          throw new CloneNotSupportedException("Invalid clone");
    //      }
    //  
    //      //可以做多种其他事情
    //      return new CloneConctr(cloneConctr.x,cloneConctr.y);
    //  }
    
    /**
     * 最佳实践
     *1)当你不知道你是否可以调用clone()方法的类你不确定如果是在这个类中实现,
     *您可以检查和检查如果类的实例“可克隆”界面如下。
     */
        //  if(obj instanceof Cloneable){
        //obj2 = obj.clone();
        //}
        //Dont do this. Cloneabe dont have any methods
        //obj2 = obj.clone();   
    }
    
    package com.object.equals.clone.conctr;
    
    /**
     * 如果要继承它的话,则需要复制子类的参数并传递参数给父类的构造器
     * @author JacXuan
     *
     */
    public class CloneConctr2 extends CloneConctr{
        private Integer z;
    
        public CloneConctr2(CloneConctr2 cloneConctr2){
            super(cloneConctr2);
            this.z = cloneConctr2.z;
        }
    }
    
    3.package com.object.equals.clone.hashtable;
    
    /**
     * 解决克隆对象和原有对象引用链表相同引起的数据篡改 单独地拷贝并组成每个桶的链表
     * 如果链表比较长,容易导致栈溢出
     * @author JacXuan
     *
     */
    public class HashTable implements Cloneable {
        private Entry[] buckets = null;
    
        private static class Entry {
            final Object key;
            Object value;
            Entry next;
    
            Entry(Object key, Object value, Entry next) {
                this.key = key;
                this.value = value;
                this.next = next;
            }
    
            Entry deepCopy() {
                //深度克隆  如果桶是空的,则clone下一个
                return new Entry(key, value, next == null ? null : next.deepCopy());
            }
        }
    
        @Override
        public HashTable clone() throws CloneNotSupportedException {
            HashTable result = (HashTable) super.clone();
            result.buckets = new Entry[buckets.length];
            for (int i = 0; i < buckets.length; i++) {
                if (buckets[i] != null) {
                    result.buckets[i] = buckets[i].deepCopy();
                }
            }
            return result;
        }
    
    }
  • 相关阅读:
    获取数据
    织梦入门2-采集1
    织梦入门1-修改
    ThinkPHP角色控制时的错误
    sublime 3打开中文乱码问题
    php抓取远程数据显示在下拉列表中
    php curl的正确使用方法
    Linux 在文件夹的所有文件中查找某字符
    webman 关于数据库性能
    虚拟机centos安装方法
  • 原文地址:https://www.cnblogs.com/qwop/p/6637302.html
Copyright © 2011-2022 走看看