美文网首页
Java深拷贝和浅拷贝

Java深拷贝和浅拷贝

作者: 二狗不是狗 | 来源:发表于2020-06-29 21:19 被阅读0次

一.等于实现变量赋值

通过等于号实现变量赋值,实际上是把copy变量也指向原来的对象,并没有创建任何新的对象和属性;例如下面的例子我们打印可以看到原来student的hashCode和copy变量的hashCode一致。


image.png
@Data
public class Subject {

    private int subjectId;

    private String subjectNumber;

    private StringBuilder subjectName;
}
@Data
public class Student {

    private int id;

    private String number;

    private StringBuilder name;

    private Subject subject;
}
public static void main(String[] args) {
    Subject subject = new Subject();
    subject.setSubjectId(1);
    subject.setSubjectNumber("aaa");
    subject.setSubjectName(new StringBuilder("aaa"));

    Student student = new Student();
    student.setId(1);
    student.setNumber("aaa");
    student.setName(new StringBuilder("aaa"));
    student.setSubject(subject);

    Student copy = student;

    copy.setId(2);
    copy.setNumber("aaabbb");
    copy.getName().append("bbb");

    copy.getSubject().setSubjectId(2);
    copy.getSubject().setSubjectNumber("aaabbb");
    copy.getSubject().getSubjectName().append("bbb");

    logger.info("student = {}", student.hashCode());
    logger.info("copy = {}", copy.hashCode());

    logger.info("subject = {}", JSON.toJSONString(subject));
    logger.info("student = {}", JSON.toJSONString(student));
}

打印结果为:
student = -859332970
copy = -859332970
subject = {"subjectId":2,"subjectName":"aaabbb","subjectNumber":"aaabbb"}
student = {"id":2,"name":"aaabbb","number":"aaabbb","subject":{"subjectId":2,"subjectName":"aaabbb","subjectNumber":"aaabbb"}}

二.浅拷贝(复制)

  1. 浅拷贝是按位拷贝对象它会创建一个新对象,例如下面的例子我们打印可以看到原来student的hashCode和copy变量的hashCode不一致。
  2. 如果属性是基本类型,拷贝的就是基本类型的值
  3. 如果属性是内存地址(引用类型),拷贝的就是内存地址
  4. 默认拷贝构造函数只是对对象进行浅拷贝复制,即只复制对象空间而不复制资源。
image.png
@Data
public class Subject {

    private int subjectId;

    private String subjectNumber;

    private StringBuilder subjectName;
}
@Data
public class Student implements Cloneable {

    private int id;

    private String number;

    private StringBuilder name;

    private Subject subject;

    @Override
    public Object clone() {
        try {
            Student student = (Student) super.clone();
            return student;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}
public static void main(String[] args) {
    Subject subject = new Subject();
    subject.setSubjectId(1);
    subject.setSubjectNumber("aaa");
    subject.setSubjectName(new StringBuilder("aaa"));

    Student student = new Student();
    student.setId(1);
    student.setNumber("aaa");
    student.setName(new StringBuilder("aaa"));
    student.setSubject(subject);

    Student copy = (Student) student.clone();

    copy.setId(2);
    copy.setNumber("aaabbb");
    copy.getName().append("bbb");

    copy.getSubject().setSubjectId(2);
    copy.getSubject().setSubjectNumber("aaabbb");
    copy.getSubject().getSubjectName().append("bbb");

    logger.info("student = {}", student.hashCode());
    logger.info("copy = {}", copy.hashCode());

    logger.info("subject = {}", JSON.toJSONString(subject));
    logger.info("student = {}", JSON.toJSONString(student));
}

打印结果为:
student = 96321
copy = -1425371071
subject = {"subjectId":2,"subjectName":"aaabbb","subjectNumber":"aaabbb"}
student = {"id":1,"name":"aaabbb","number":"aaa","subject":{"subjectId":2,"subjectName":"aaabbb","subjectNumber":"aaabbb"}}

三.深拷贝(复制)

  1. 对于基本数据类型的成员对象,因为基础数据类型是值传递的,所以是直接将属性值赋值给新的对象。基础类型的拷贝,其中一个对象修改该值,不会影响另外一个(和浅拷贝一样)。
  2. 对于引用类型,比如数组或者类对象,深拷贝会新建一个对象空间,然后拷贝里面的内容,所以它们指向了不同的内存空间。改变其中一个,不会对另外一个也产生影响。
  3. 对于有多层对象的,每个对象都需要实现 Cloneable 并重写 clone() 方法,进而实现了对象的串行层层拷贝。
  4. 深拷贝相比于浅拷贝速度较慢并且花销较大。
  5. 下面的例子因为String类和StringBuilder类没有实现Cloneable接口,所以是浅拷贝
image.png
@Data
public class Subject implements Cloneable {

    private int subjectId;

    private String subjectNumber;

    private StringBuilder subjectName;

    @Override
    public Object clone() {
        try {
            Subject subject = (Subject) super.clone();
            return subject;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}
@Data
public class Student implements Cloneable {

    private int id;

    private String number;

    private StringBuilder name;

    private Subject subject;

    @Override
    public Object clone() {
        try {
            Student student = (Student) super.clone();
            student.setSubject((Subject) subject.clone());
            return student;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}
public static void main(String[] args) {
    Subject subject = new Subject();
    subject.setSubjectId(1);
    subject.setSubjectNumber("aaa");
    subject.setSubjectName(new StringBuilder("aaa"));

    Student student = new Student();
    student.setId(1);
    student.setNumber("aaa");
    student.setName(new StringBuilder("aaa"));
    student.setSubject(subject);

    Student copy = (Student) student.clone();

    copy.setId(2);
    copy.setNumber("aaabbb");
    copy.getName().append("bbb");

    copy.getSubject().setSubjectId(2);
    copy.getSubject().setSubjectNumber("aaabbb");
    copy.getSubject().getSubjectName().append("bbb");

    logger.info("student = {}", student.hashCode());
    logger.info("copy = {}", copy.hashCode());

    logger.info("subject = {}", JSON.toJSONString(subject));
    logger.info("student = {}", JSON.toJSONString(student));
}

打印结果为:
student = 96321
copy = -1425371071
subject = {"subjectId":1,"subjectName":"aaabbb","subjectNumber":"aaa"}
student = {"id":1,"name":"aaabbb","number":"aaa","subject":{"subjectId":1,"subjectName":"aaabbb","subjectNumber":"aaa"}}

相关文章

  • java 对象的拷贝

    拷贝:即复制 对象拷贝:即对象复制 java 对象拷贝分类:浅拷贝、深拷贝 java 对象的浅拷贝和深拷贝针对包含...

  • Java基础 - 深拷贝和浅拷贝

    Java 的深拷贝和浅拷贝 什么是深拷贝、浅拷贝 (深克隆、浅克隆)? 在 Java 中,数据类型分为 基本数据类...

  • java中的深拷贝和浅拷贝

    简单记录一下java中的深拷贝和浅拷贝,深拷贝和浅拷贝只是针对对象而言的. 1 深拷贝代码 2 浅拷贝代码 3 测...

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • Java------List的深拷贝与浅拷贝

    Java的浅拷贝(Shallow Copy)、深拷贝(Deep Copy)。 浅拷贝(Shallow Copy) ...

  • Java的浅拷贝和深拷贝

    首先需要明白,浅拷贝和深拷贝都是针对一个已有对象的操作。那先来看看浅拷贝和深拷贝的概念。 在 Java 中,除了基...

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • 深克隆--何时是尽头?

    As we all know Java有两种拷贝,浅拷贝和深拷贝,高大上的叫法也叫浅克隆和深克隆。 深克隆有时会碰...

  • iOS - copy 与 mutableCopy

    一说到拷贝,就不得不提浅拷贝和深拷贝。 何谓浅拷贝?何谓深拷贝? 往简单的说: 浅拷贝:拷贝地址。 深拷贝:拷贝内...

  • 关于Java的浅拷贝和深拷贝

    浅拷贝和深拷贝是什么? 浅拷贝和深拷贝都是针对已经存在了的对象的操作,在java中,基本数据类型有八种,和引用数据...

网友评论

      本文标题:Java深拷贝和浅拷贝

      本文链接:https://www.haomeiwen.com/subject/ipnafktx.html