1    重点关注

1.1    使用场景

除非拷贝数组,或者做系统镜像相关,有些专家级的程序员从来不去覆盖clone方法,也从来不去调用它。

 

1.2    参考原型模式

https://www.cnblogs.com/1446358788-qq/p/11456714.html

 

1.3    奇怪

深拷贝的递归方法的使用

 

 

2    课程目的

 

 

3    代码演练

3.1    克隆覆盖_如果每个域中包含一个基本类型的值,或者指向一个不可变对象的引用。

package com.ddwei.test.core.chapter11.demo1;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class PhoneNumber implements Cloneable{

    @Override
    public PhoneNumber clone(){
        try {
            return  (PhoneNumber) super.clone();
        } catch (CloneNotSupportedException e) {
            //打印堆栈信息
            log.error(JSON.toJSONString(e));
            throw new Error();
        }
    }

}

 

3.2    克隆覆盖_对象包含域中引入了可变对象

package com.ddwei.test.core.chapter11.demo2;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.EmptyStackException;

@Slf4j
public class Stack3 implements Cloneable{

    private Object[] elements;
    private static final int DEFALUT_INITIAL_CAPACITY = 16;
    private int size = 0;

    public Stack3(){
        elements = new Object[DEFALUT_INITIAL_CAPACITY ];
    }

    /**
     * 栈移入元素
     * @author weidoudou
     * @date 2022/6/27 12:52
     * @param obj 请添加参数描述
     * @return void
     **/
    public void push(Object obj){
        //
       ensurCapacity();
       elements[size++] = obj;
    }

    /**
     * 栈移除元素
     * @author weidoudou
     * @date 2022/6/27 12:51
     * @param
     * @return java.lang.Object
     **/
    public Object pop(){
        if(size == 0){
            throw new EmptyStackException();
        }
        Object result = elements[--size];
        elements[size] = null;
        return result;
    }

    /**
     * 预先设置数组的大小,每次数组元素不够的时候,进行扩充两倍
     * @author weidoudou
     * @date 2022/6/27 12:49
     * @param
     * @return void
     **/
    public void ensurCapacity(){
        if(elements.length == size){
            elements = Arrays.copyOf(elements,2*size+1);
        }
    }

    /**
     * 克隆方法就是另一个构造器,你必须确保它不伤害到原始对象,并确保正确的创建被克隆对象中的约束条件。
     * 为了使Stack类中的clone方法正常工作,必须要拷贝栈的内部信息,最容易的做法是,在elements数组中递归的调用clone
     * @author weidoudou
     * @date 2022/9/5 13:15
     * @param
     * @return com.ddwei.test.core.chapter11.demo2.Stack3
     **/
    @Override
    public Stack3 clone(){
        try {
            Stack3 stack3 = (Stack3)super.clone();
            stack3.elements = elements.clone();
            return stack3;
        } catch (CloneNotSupportedException e) {
            log.error(JSON.toJSONString(e));
            throw new Error();
        }
    }


}

 

 

3.3    克隆覆盖_避免浅拷贝 出现修改克隆对象,源对象受到影像

package com.ddwei.test.core.chapter11.demo3;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class HashTable implements Cloneable{
    private Entry[] buckets;

    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(){
            return new Entry(key,value,next==null?null:next.deepCopy());
        }
    }

    @Override
    public HashTable clone(){
        try {
            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;
        } catch (CloneNotSupportedException e) {
            log.error(JSON.toJSONString(e));
            throw new Error();
        }
    }
}

 

3.4    克隆覆盖_避免递归调用容易造成的堆栈溢出等问题,直接使用迭代调用深拷贝

package com.ddwei.test.core.chapter11.demo4;

import com.alibaba.fastjson.JSON;
import com.ddwei.test.core.chapter11.demo3.HashTable;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class HashTable2 {
    private Entry[] buckets;

    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(){
            Entry result = new Entry(key,value,next);

            for(Entry p=result; p.next!=null ;p=p.next){
                p.next = new Entry(p.next.key,p.next.value,p.next.next);
            }
            return result;
        }
    }

    @Override
    public HashTable2 clone(){
        try {
            HashTable2 result = (HashTable2) 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;
        } catch (CloneNotSupportedException e) {
            log.error(JSON.toJSONString(e));
            throw new Error();
        }
    }
}

 

posted on 2022-07-15 08:35  菜鸟乙  阅读(19)  评论(0编辑  收藏  举报