• 支持泛型的克隆接口和克隆类
    • 我们解决什么问题
    • 泛型克隆接口
    • 泛型克隆类
    • 深克隆

    支持泛型的克隆接口和克隆类

    我们解决什么问题

    我们知道,JDK中的Cloneable接口只是一个空接口,并没有定义成员,它存在的意义仅仅是指明一个类的实例化对象支持位复制(就是对象克隆),如果不实现这个类,调用对象的clone()方法就会抛出CloneNotSupportedException异常。而且,因为clone()方法在Object对象中,返回值也是Object对象,因此克隆后我们需要自己强转下类型。

    泛型克隆接口

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

    1. /**
    2. * 猫猫类,使用实现Cloneable方式
    3. * @author Looly
    4. *
    5. */
    6. private static class Cat implements Cloneable<Cat>{
    7. private String name = "miaomiao";
    8. private int age = 2;
    9. @Override
    10. public Cat clone() {
    11. try {
    12. return (Cat) super.clone();
    13. } catch (CloneNotSupportedException e) {
    14. throw new CloneRuntimeException(e);
    15. }
    16. }
    17. }

    泛型克隆类

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

    1. /**
    2. * 狗狗类,用于继承CloneSupport类
    3. * @author Looly
    4. *
    5. */
    6. private static class Dog extends CloneSupport<Dog>{
    7. private String name = "wangwang";
    8. private int age = 3;
    9. }

    当然,使用CloneSupport的前提是你没有继承任何的类,谁让Java不支持多重继承呢(你依旧可以让父类实继承这个类,如果可以的话)。如果没办法继承类,那实现cn.hutool.clone.Cloneable也是不错的主意,因此hutool提供了这两种方式,任选其一,在便捷和灵活上都提供了支持。

    深克隆

    我们知道实现Cloneable接口后克隆的对象是浅克隆,要想实现深克隆,请使用:

    1. ObjectUtil.cloneByStream(obj)

    前提是对象必须实现Serializable接口。

    ObjectUtil同样提供一些静态方法:clone(obj)cloneIfPossible(obj)用于简化克隆调用,详细的说明请查看核心类的相关文档。