深複製與淺複製區別
在 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。