java的clone()方法

什么是"clone"? 

  在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能 会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。在 Java语言中,用简单的赋值语句是不能满足这种需求的。要满足这种需求虽然有很多途径,但实现clone()方法是其中最简单,也是最高效的手段。 

   Java的所有类都默认继承java.lang.Object类,在java.lang.Object类中有一个方法clone()。JDK API的说明文档解释这个方法将返回Object对象的一个拷贝。要说明的有两点:一是拷贝对象返回的是一个新对象,而不是一个引用。二是拷贝对象与用 new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。 

如何使用clone方法

首先需要实现CloseAble类

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

浅复制:

1、创建类Student

public class Student implements  Cloneable {

    private String name;
    private int age;
    private Professor professor;

    public Student(String name, int age, Professor professor) {
        this.name = name;
        this.age = age;
        this.professor = professor;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public Professor getProfessor() {
        return professor;
    }

    public void setProfessor(Professor professor) {
        this.professor = professor;
    }

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

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

2、创建类Professor

public class Professor{
    private String name;
    private int age;

    public Professor(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

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

3、执行

 @Test
    public void cloneT(){
        Professor p1 = new Professor("Professor Zhang",30);

        Student s1 = new Student("xiao ming",18,p1);

        System.out.println(s1);

        try {
            Student s2 = (Student) s1.clone();
            s2.setName("xiao hong");
            s2.setAge(17);
            Professor p2 = s2.getProfessor();
            p2.setName("Professor Li");
            p2.setAge(45);
            s2.setProfessor(p2);
            System.out.println("复制后的:s1 = " + s1);
            System.out.println("复制后的:s2 = " + s2);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

    }

4、运行结果:

1 Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
2 复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]]
3 复制后的:s2 = Student [name=xiao hong, age=17, professor=Professor [name=Professor Li, age=45]]

问题:发现修改s2的Professor,对应的s1也变了,但是基本类型 name和age没有跟着改变。这主要是浅复制带来的问题,若要解决这个问题,需要使用深复制。

深复制:

1、为Professor 类添加clone方法

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

2、修改Student的clone方法

 @Override
    public Object clone() throws CloneNotSupportedException {
        Student s = null;
        try {
            s = (Student) super.clone();
            s.professor = (Professor) this.professor.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return s;
    }

3、输出结果

1 Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
2 复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
3 复制后的:s2 = Student [name=xiao hong, age=17, professor=Professor [name=Professor Li, age=45]]

参考地址:https://www.cnblogs.com/acode/p/6306887.html

猜你喜欢

转载自www.cnblogs.com/cq-yangzhou/p/10751508.html
今日推荐