1、clone();======>父类默认的拷贝方法是浅拷贝。父类中的修饰符是:protected

浅拷贝:

Person类中,实现implements Cloneable接口

@Override
重写clone()这个父类方法后,还需要把protected改为public,
类型是当前重写的子类类型才能正常使用
protected Object clone() throws CloneNotSupportedException {
    return super.clone();
}

 

public class boy {
    String name;
    int age;
    //get、set、有参无参构造、toString方法
}
public class Person implements Cloneable{
    String name;
    String sex;
    int age;
    boy boy;
}
public class Test2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person();
        p1.setName("李白");
        p1.setSex("女");
        p1.setAge(18);
        Person p2 = p1.clone();
        System.out.println(p1+"===="+p1.hashCode());
        System.out.println(p2+"===="+p2.hashCode());

        boy b = new boy();
        b.setName("小孩");
        b.setAge(3);
        p1.setBoy(b);
        Person p3 = p1.clone();
        System.out.println(p1+"========"+p1.hashCode()+"====="+p1.getBoy().hashCode());
        System.out.println(p1+"========"+p3.hashCode()+"======="+p1.getBoy().hashCode());
    }
}

  结论:

    •   通过测试发现克隆出来的对象虽然不一致,但是底层的成员变量的哈希值是一致的。这种复制我们称之为:浅表复制。

  浅表复制的内存结构:

  浅表复制的弊端

    •   由于浅表复制导致克隆的对象中成员变量的底层哈希值一致。
    •   如果我们操作其中一个对象的的某个成员变量(比如改变boy类里的name值)内容,就会导致,所有的克隆对象的成员内容(boy.name值)发生改变。

深层复制:

//    Person类中,实现implements Cloneable接口

//    深表复制从写clone()方法

    @Override
    public Person clone() throws CloneNotSupportedException {
        Person pc = (Person) super.clone();
//        boy类中也要重写clone()方法
        pc.setBoy(boy.clone());
        return pc;
    }
//boy类实现Cloneable方法
//    重写clone()方法
    @Override
    public boy clone() throws CloneNotSupportedException {
        return (boy) super.clone();
    }
public static void main(String[] args) throws CloneNotSupportedException {
    Person p1 = new Person();
    p1.setName("李白");
    p1.setAge(12);
    p1.setSex("女");
    boy b = new boy();
    b.setName("十三娘");
    b.setAge(18);
    p1.setBoy(b);
    Person p2 = p1.clone();
    System.out.println(p1+"======="+p1.hashCode()+"========"+p1.getBoy().hashCode());
    System.out.println(p2+"======="+p2.hashCode()+"========"+p2.getBoy().hashCode());
    b.setName("许七安");
    p2.setBoy(b);
    System.out.println(p2+"======="+p2.hashCode()+"========"+p2.getBoy().hashCode());
}

   

深层复制的内存结构:

结论:

  使用克隆接口完成深度复制的弊端:

    • 当Person类中存在多个类属性时
    • 重复实现Cloneable接口
    • 重复实现clone方法
    • 重复改写Person类的clone方法   

   可以使用IO流的方式进行复制操作(深度复制),可以解决重复修改源代码的问题。

      • Person类需要实现Cloneable和Serialization接口
      • Person中的两个类属性也需要实验Serialization接口,但不用再重写clone()方法了

posted on   菜鸟Curry  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通



点击右上角即可分享
微信分享提示