Hutool(二)

517 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情

四、克隆操作

对于浅拷贝来说,当成员变量引用类型时,浅拷贝拷贝的是地址;当成员变量基本类型时,浅拷贝拷贝的是

对于深拷贝来说,无论成员变量是基本类型还是引用类型,采用的都是值传递,而不是拷贝了一个地址。

1. 以前如何克隆

浅拷贝

  • 实现JDK中的Cloneable接口,并重写**clone()**方法

JDK中的Cloneable接口只是一个空接口,并没有定义成员,它存在的意义仅仅是指明一个类的实例化对象支持位复制(就是对象克隆),Object中有clone()方法,我们需要实现重写clone()方法并且我们需要自己强转下类型

深拷贝

  • 方法一:
    • 对于引用类型的成员变量也实现浅拷贝就好了,也就是无限递归下去
  • 方法二:
    • 通过对象序列化和反序列化首先深拷贝(推荐)
    • 实现Serializable接口,然后自定义拷贝方法deepClone(),详细见深拷贝

2. Hutools中如何克隆

浅拷贝

  • 方法一:Cloneable 接口

    cn.hutool.core.clone.Cloneable接口,此接口定义了一个返回泛型的成员方法,这样,实现此接口后会提示必须实现一个public的clone方法,调用父类clone方法即可:

    /**
     * 猫猫类,使用实现Cloneable方式
     */
    private static class Cat implements Cloneable<Cat>{
        private String name = "miaomiao";
        private int age = 2;
        
        @Override
        public Cat clone() {
            try {
                return (Cat) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new CloneRuntimeException(e);
            }
        }
    }
    
  • 方法二:继承 CloneSupport 类

    实现cn.hutool.core.clone.Cloneable接口实现浅拷贝依旧有不方便之处,就是必须自己实现一个public类型的clone()方法,还要调用父类(Object)的clone方法并处理异常。于是cn.hutool.clone.CloneSupport类产生,这个类帮我们实现了上面的clone方法,因此只要继承此类,不用写任何代码即可使用clone()方法:

    /**
     * 狗狗类,用于继承CloneSupport类
     *
     */
    private static class Dog extends CloneSupport<Dog>{
        private String name = "wangwang";
        private int age = 3;
    }
    

    上面两种方式肯定继承CloneSupport类更方便,但是如果需要实现克隆的类已经继承了其他类,无法再继承CloneSupport 类,那么只能实现Cloneable 接口了,因为java只支持单继承,但是支持多实现

  • 方法三:

深拷贝

  • 方法一:直接调用hutools的cloneByStream()方法,前提是对象必须实现Serializable接口,如果对象中的一些属性也是对象的话,属性对象所属的类也必须实现 Serializable接口

    ObjectUtil.cloneByStream(obj)
    
  • 方法二:直接调用hutools的clone方法,前提是对象必须实现Serializable接口,当然如果对象中的一些属性也是对象的话,属性对象所属的类也必须实现 Serializable接口

    ObjectUtil.clone(obj)