深拷贝与浅拷贝区别
在 Java 中,除了基本数据类型(元类型)之外,还存在类的实例对象这个引用数据类型。而一般使用 『 = 』号做赋值操作的时候。对于基本数据类型,实际上是拷贝的它的值,但是对于对象而言,其实赋值的只是这个对象的引用,将原对象的引用传递过去,他们实际上还是指向的同一个对象。
而浅拷贝和深拷贝就是在这个基础之上做的区分,如果在拷贝这个对象的时候,只对基本数据类型进行了拷贝,而对引用数据类型只是进行了引用的传递,而没有真实的创建一个新的对象,,则认为是浅拷贝。反之,在对引用数据类型进行拷贝的时候,创建了一个新的对象,并且复制其内的成员变量,则认为是深拷贝。
hutool BeanUtil.copyProperties 浅拷贝问题重现
@Test public void testCopy(){ Student.Transcript transcript = Student.Transcript.builder().score(100).build(); Student student = Student.builder().id(1).transcript(transcript).build(); System.out.println("student = " + student); Student copyStudent = BeanUtil.copyProperties(student,Student.class); System.out.println("copyStudent = " + copyStudent); Student.Transcript studentTranscript = student.getTranscript(); studentTranscript.setScore(99); student.setId(2); System.out.println("student = " + student); System.out.println("copyStudent = " + copyStudent); } @Builder @Data static class Student{ Integer id; Transcript transcript; @Builder @Data static class Transcript{ int score; } }
执行结果
student = Student(id=1, transcript=Student.Transcript(score=100)) copyStudent = Student(id=1, transcript=Student.Transcript(score=100)) student = Student(id=2, transcript=Student.Transcript(score=99)) copyStudent = Student(id=1, transcript=Student.Transcript(score=99))
在代码中,我们对原有的student实例进行了两个修改,分别是id赋值为2,student内的transcript score重新赋值。
从执行结果可以看到,在对student实例Transcript对象进行修改后,复制得到的copyStudent也发生了相应的变动,但copyStudent的id仍然是1,没有跟随student的id。