1. 程式人生 > 其它 >spring下的beanutils.copyProperties方法是深拷貝還是淺拷貝?可以實現深拷貝嗎?

spring下的beanutils.copyProperties方法是深拷貝還是淺拷貝?可以實現深拷貝嗎?

一、淺拷貝深拷貝的理解

簡單說拷貝就是將一個類中的屬性拷貝到另一箇中,對於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());