spring下的beanutils.copyProperties方法是深拷貝還是淺拷貝?可以實現深拷貝嗎?
阿新 • • 發佈:2022-05-24
一、淺拷貝深拷貝的理解
簡單說拷貝就是將一個類中的屬性拷貝到另一箇中,對於BeanUtils.copyProperties來說,你必須保證屬性名和型別是相同的,因為它是根據get和set方法來賦值的。
1.1、淺拷貝
淺拷貝可以理解為如果是引用型別,那麼目標物件拷貝的只是源物件的地址,無論目標物件還是源物件改變,他們都會一起改變
1.2、深拷貝
深拷貝就是將目標物件的屬性全部複製一份給源物件,複製完之後他們就是隔開的,沒有任何關係,無論操作源物件還是目標物件都對另一個沒有影響
無論是淺拷貝還是深拷貝,對於基本型別和String來說都是沒有影響的,有影響的只有引用型別資料
二、beanutils.copyProperties是淺拷貝還是深拷貝?
答案:淺拷貝
三、測試beanutils.copyProperties為淺拷貝
建兩個實體類
public class CityBean { String value; .......// 省略get和set方法,Alt+insert很快的 }
public class FastdfsTest { private String id; private String name; private String size; private CityBean cityBean; .......// 省略get和set方法,Alt+insert很快的
測試:
@Test public void testObjectMapper() throws IOException, MyException { // 源類 FastdfsTest source = new FastdfsTest(); source.setId("fastdfsTest"); source.setName("fastdfsTest"); source.setSize("fastdfsTest"); CityBean cityBean = new CityBean(); cityBean.setValue("CityBean源值"); source.setCityBean(cityBean); // 目標類 FastdfsTest target = new FastdfsTest(); // 把fastdfsTest中所有的屬性都複製到fastdfsTestCopy中,即使是cityBean也會被複制 BeanUtils.copyProperties(source,target); CityBean sourceCity = source.getCityBean(); //在下面改變源類的引用資料,如果BeanUtils.copyProperties是淺拷貝,那麼目標類拷貝的就是一個引用地址;源類改變目標類也會跟著改變 //如果BeanUtils.copyProperties是深拷貝,則兩邊改變都不會相互影響 sourceCity.setValue("CityBean目標值"); System.out.println(source.toString() == target.toString()); }
測試截圖:
這裡可以看出BeanUtils.copyProperties是一個淺拷貝
四、如何用beanutils.copyProperties實現深拷貝
測試程式碼
/** * 測試stream中用BeanUtils.copyProperties是否是深拷貝 */ @Test public void testStream(){ // 我從資料庫查的,其實就是建立幾個資料,這裡就自己添加了哈 List<FastdfsTest> fastdfsTestList = fastdfsTestService.selectFastdfsTestList(); // 先構造 fastdfsTestList = fastdfsTestList.stream().map(k -> { CityBean cityBean = new CityBean(); cityBean.setValue("新的value"); k.setCityBean(cityBean); return k; }).collect(Collectors.toList()); // 拷貝 List<FastdfsTest> fastdfsTestList2 = fastdfsTestList.stream().map(k -> { FastdfsTest fastdfsTest = new FastdfsTest(); BeanUtils.copyProperties(k,fastdfsTest); return fastdfsTest; }).collect(Collectors.toList()); // 設定源物件引用欄位為空 fastdfsTestList.get(0).setCityBean(null); System.out.println(fastdfsTestList + "==userDTOList==" + fastdfsTestList2); }
測試截圖
這裡可以看到改變源物件是不會影響目標物件的,因此可以藉助java8的一些stream新特性,用BeanUtils.copyProperties這個方法來實現深拷貝(任意兩個類都可以哦)
深拷貝模板
// 拷貝 List<目標型別> target= source.stream().map(k -> { 目標型別 xxx= new 目標型別(); BeanUtils.copyProperties(k,xxx); return xxx; }).collect(Collectors.toList());