zl程序教程

您现在的位置是:首页 >  其它

当前栏目

初识Object的clone()

object 初识 clone
2023-06-13 09:15:30 时间

浅拷贝(Shadow Clone)

对基本数据类型进行值传递,对引用数据类型进行引用传递的拷贝。

创建一个User类,试验下clone()方法

public class User implements Cloneable{
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
  
      @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public static void main(String[] args) {
        User user = new User();
        user.setName("小提手");
        user.setAge(18);
        System.out.println("source user = " + user);

        System.out.println();

        User clone = (User) user.clone();
        System.out.println("clone user = " + clone);

        System.out.println();
        System.out.println("----- clone after 进行赋值操作 -----");
        System.out.println();

        clone.setAge(25);
        System.out.println("source user = " + user);
        System.out.println("clone user = " + clone);
    }
}

好像跟他说的不一样呀,浅拷贝对象内容也不一样了,问题出在哪里呢?对第一句话反复的研读,才发现,我这只是在修改基本类型,所以age的值是不一样了。为了实验我的想法,有新增了一个类:

public class Person implements Cloneable
{
    private String name;
    private User user;

    public String getName() {
        return name;
    }

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

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

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

    public static void main(String[] args) {
        User user = new User();
        user.setName("小提手");
        user.setAge(18);

        Person person = new Person();
        person.setName("程序员");
        person.setUser(user);
        System.out.println("person = " + person);


        Person clone = (Person) person.clone();
        System.out.println("clone = " + clone);

        System.out.println();
        clone.setName("管理员");
        clone.getUser().setAge(25);

        System.out.println("person = " + person);
        System.out.println("clone = " + clone);
    }
}

从这可以发现,对于拷贝的对象,我分别修改了基本类型和引用类型的内容,基本类型的值是只修改了拷贝对象的内容,源对象的内容值不会跟着改变;但是修改引用类型的值,会将源对象的也一起改变。

深拷贝(Deep Clone)

对基本数据类型进行值传递,为数据类型创建一个新的对象,并且复制其内容的拷贝。

将上面的代码进行修改:

重写Object类的clone()方法。

public class User implements Cloneable{
    private String name;
    private Integer age;

		//...

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

重写Object类的clone()方法。

public class Person implements Cloneable
{
    private String name;
    private User user;

		//...

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person clone = (Person) super.clone();
        clone.setUser((User) user.clone());
        return clone;
    }
}

测试:

public static void main(String[] args) throws CloneNotSupportedException {
        User user = new User();
        user.setName("小提手");
        user.setAge(18);

        Person person = new Person();
        person.setName("程序员");
        person.setUser(user);
        System.out.println("person = " + person);


        Person clone = (Person) person.clone();
        System.out.println("clone = " + clone);

        System.out.println();
        clone.setName("管理员");
        clone.getUser().setAge(25);

        System.out.println("person = " + person);
        System.out.println("clone = " + clone);
    }
}

结果:

发现的确是复制了引用类型的内容,克隆对象与源对象内容的值互不干扰。