1.引用拷贝

1.1 引用拷贝示例

class Sudo {
    private int pid;

    public Sudo(int pid) {
        this.pid = pid;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }

    public int getPid() {
        return pid;
    }

    public static void main(String[] args) {
        Sudo sudo = new Sudo(0);
        Sudo sudo1 = sudo;
        System.out.println(sudo);
        System.out.println(sudo1);
        System.out.println(sudo==sudo1);
    }
}

1.1.1 执行结果

com.zyyx.sms.vo.Sudo@7aec35a
com.zyyx.sms.vo.Sudo@7aec35a
true

image.png
从输出结果可以得出,sudo与sudo1的地址值是相同的也就是说它们是同一个对象 他们都指向同一个引用 这个就叫做 引用拷贝

1.1.2 引用拷贝描述

引用拷贝会生成一个新的对象引用地址,但是两个最终指向依然是同一个对象

2. 浅拷贝

在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址

简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。

  • 被复制的类需要实现Clonenable接口(不实现的话在调用clone方法会抛出CloneNotSupportedException异常), 该接口为标记接口(不含任何方法)

  • 覆盖clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象。

2.2 对象拷贝示例



class Sudo implements Cloneable {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Sudo{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    @Override
    public Object clone() {
        Object object = null;
        try {
            object = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return object;
    }
}

class Tear implements Cloneable {
    private String name;
    private String age;
    private Sudo sudo;

    public Sudo getSudo() {
        return sudo;
    }

    public void setSudo(Sudo sudo) {
        this.sudo = sudo;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public Object clone() {
        Object object = null;
        try {
            object = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return object;
    }

    @Override
    public String toString() {
        return "Tear{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", sudo=" + sudo +
                '}';
    }

    public static void main(String[] args) {
        Sudo sudo = new Sudo();
        sudo.setAge("20");
        sudo.setName("李四");
        Tear tear = new Tear();
        tear.setName("张三");
        tear.setAge("18");
        tear.setSudo(sudo);
        System.out.println("原tear" + tear);
        Tear tears = (Tear) tear.clone();
        System.out.println("Clone tear" + tears);

        sudo.setName("王五");
        System.out.println("修改后原tear" + tear);
        System.out.println("修改后Clone tear" + tears);
    }
}




2.2 执行结果

com.zyyx.sms.vo.Sudo@7aec35a
com.zyyx.sms.vo.Sudo@67424e82
false

从输出结果可以看出两个对象的地址是不相同的,创建了新的对象,而不是像引用拷贝把地址赋值给另一个对象,叫作 对象拷贝

3.深拷贝