Java 深浅拷贝

引用拷贝、对象拷贝、浅拷贝、深拷贝

1、什么是引用拷贝

拷贝时只拷贝了一个对象的引用,使得拷贝引用和被拷贝引用指向同一个对象

Student a = new Student();
Student b = a;

2、什么是对象拷贝

拷贝时会将待拷贝的对象创建一个新的放在堆中,然后生成一个新的引用指向它。
前提是Student重写了了clone方法,注意不需要非得继承Cloneable接口,只是一个声明接口

  • clone()接口是Object类中一个protected final方法
Student a = new Student();
Student b = (Student)a.clone();

3、浅拷贝和深拷贝

首先要说明的是,浅拷贝和深拷贝都是属于对象拷贝的
所不同的在于:

  • 对于浅拷贝,待拷贝类中的基本数据类型是值传递,引用类型只是引用拷贝
  • 对于深拷贝,待拷贝类中的基本数据类型是值传递,引用类型也是对象拷贝,该对象如果也有引用变量也需要递归下去
  • 深拷贝需要自己在clone()方法中维护

如下是潜拷贝(上)和深拷贝(下)的对象图

  • Student类中有引用变量Teacher

潜拷贝
深拷贝

4、代码实现

4.1、引用拷贝
package copy;

/**
 * 引用拷贝
 */
public class QuoteCopy {
    public static void main(String[] args) {
        QuoteTeacher quoteTeacher = new QuoteTeacher("riemann", 28);
        QuoteTeacher otherQuoteTeacher = quoteTeacher;
		// 输出一样
        System.out.println(quoteTeacher);
        System.out.println(otherQuoteTeacher);
    }
}

class QuoteTeacher {
    private String name;
    private int age;

    public QuoteTeacher(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // get set...
}
4.2、对象拷贝
package copy;

/**
 * 对象拷贝
 * 深拷贝和浅拷贝都是对象拷贝
 */
public class ObjectCopy {
    public static void main(String[] args) throws CloneNotSupportedException {

        ObjectTeacher teacher = new ObjectTeacher("Richard Feynman", 25);
        ObjectTeacher teacher2 = (ObjectTeacher) teacher.clone();

        System.out.println(teacher);
        System.out.println(teacher2);

    }


}

class ObjectTeacher implements Cloneable {
    private String name;
    private int age;

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

    // get set...

    // 重写 Object类中的clone,方法体内调用Object类中的native方法
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
4.3、浅拷贝
package copy.shallow;

/**
 * 潜拷贝
 */
public class ShallowCopy {
    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher teacher = new Teacher();
        teacher.setName("riemann");
        teacher.setAge(28);

        Student student1 = new Student();
        student1.setName("edgar");
        student1.setAge(18);
        student1.setTeacher(teacher);

        Student student2 = (Student) student1.clone();
        System.out.println("-------------拷贝后-------------");
        System.out.println(student2.getName());
        System.out.println(student2.getAge());
        System.out.println(student2.getTeacher().getName());
        System.out.println(student2.getTeacher().getAge());

        System.out.println("-------------修改老师的信息后-------------");
        // 修改老师的信息
        teacher.setName("jack");
        System.out.println("student1的teacher为: " + student1.getTeacher().getName());
        System.out.println("student2的teacher为: " + student2.getTeacher().getName());

    }
}


class Teacher implements Cloneable {
    private String name;
    private int age;

	// get set (name, age)
}


class Student implements Cloneable {
    private String name;
    private int age;
    // 深浅拷贝就是看类中的引用对象是否是对象拷贝
    private Teacher teacher;

    // get set (name, age)

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
	// 和对象拷贝一样
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
4.4、深拷贝
package copy.deap;

public class DeepCopy {

    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher teacher = new Teacher();
        teacher.setName("riemann");
        teacher.setAge(28);

        Student student1 = new Student();
        student1.setName("edgar");
        student1.setAge(18);
        student1.setTeacher(teacher);

        Student student2 = (Student) student1.clone();
        System.out.println("-------------拷贝后-------------");
        System.out.println(student2.getName());
        System.out.println(student2.getAge());
        System.out.println(student2.getTeacher().getName());
        System.out.println(student2.getTeacher().getAge());

        System.out.println("-------------修改老师的信息后-------------");
        // 修改老师的信息
        teacher.setName("jack");
        System.out.println("student1的teacher为: " + student1.getTeacher().getName());
        System.out.println("student2的teacher为: " + student2.getTeacher().getName());

    }
}


class Teacher implements Cloneable {
    private String name;
    private int age;

    // get set (name, age) 

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Student implements Cloneable {
    private String name;
    private int age;
    private Teacher teacher;

    // get set (name, age)

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    public Object clone() throws CloneNotSupportedException {
        // 浅拷贝时:
        // Object object = super.clone();
        // return object;

        // 改为深拷贝:
        Student student = (Student) super.clone();
        // 本来是浅拷贝,现在将Teacher对象复制一份并重新set进来
        student.setTeacher((Teacher) student.getTeacher().clone());
        return student;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值