浅拷贝与深拷贝以及BeanUtils.copyProperties()

浅拷贝:BeanUtils.copyProperties();是属于浅拷贝的。
浅拷贝即是只拷贝了对象的属性,比如原始对象A,拷贝到B,如果对象A的属性还是一个对象,并不会对属性的对象进行copy,而是直接引用,如果直接一个属性是对象x,直接修改该对应对象x的属性,是会对原始对象A也最到修改的,具体看一下的测试代码

深度拷贝:可以通过序列化和反序列化来实现
深度拷贝即是拷贝对应的属性,以及如果属性是对象的话,也会对其属性做拷贝。

import java.io.*;
import java.util.List;

public class DeepCopyUtil {
    /**
     * 对象深拷贝需要model实现Serializable
     */
    public static <T> T deepCopy(T t) {
        ByteArrayOutputStream byteOut = null;
        ObjectOutputStream out = null;
        ByteArrayInputStream byteIn = null;

        try {
            // 写入字节流
            byteOut = new ByteArrayOutputStream();
            out = new ObjectOutputStream(byteOut);
            out.writeObject(t);

            byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(byteIn);
            return (T) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            throw new BaseException("deepCopy failure!! error=" + e.getMessage());
        } finally {
            try {
                if (byteOut != null) {
                    byteOut.close();
                }
                if (byteIn != null) {
                    byteIn.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                throw new BaseException("deepCopy serial close error=" + e.getMessage());
            }
        }
    }
}

看如下测试代码:

import org.springframework.beans.BeanUtils;


import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.*;

class Obj implements Serializable {
    List<String> nameList;
    String id;

    public List<String> getNameList() {
        return this.nameList;
    }

    public void setNameList(final List<String> nameList) {
        this.nameList = nameList;
    }

    public String getId() {
        return this.id;
    }

    public void setId(final String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Obj{" +
                "nameList=" + nameList +
                ", id='" + id + '\'' +
                '}';
    }
}


public class ExcelTest {

    public static void  test2() {
        Obj obj1 = new Obj();
        obj1.setId("555");
        List<String> names = new ArrayList<>();
        names.add("xxx");
        names.add("yyy");
        obj1.setNameList(names);
        //深度拷贝
        Obj obj2 = DeepCopyUtil.deepCopy(obj1);

        //浅拷贝
        Obj obj3 = new Obj();
        BeanUtils.copyProperties(obj1,obj3);

        obj2.getNameList().set(0,"chw");
        System.out.println("obj1:"+obj1);
        System.out.println("obj2:"+obj2);

        obj3.getNameList().set(0,"ccc");
        System.out.println("obj1:"+obj1);
        System.out.println("obj3:"+obj3);
    }

    public static void main(String[] args)  {
        test2();
    }
}
// obj2是对obj1的深度拷贝,修改obj2的子对象不会修改到obj1
// obj3是对obj1的浅拷贝,修改obj3的子对象会修改到obj1
// obj1:Obj{nameList=[xxx, yyy], id='555'}
// obj2:Obj{nameList=[chw, yyy], id='555'}
// obj1:Obj{nameList=[ccc, yyy], id='555'}
// obj3:Obj{nameList=[ccc, yyy], id='555'}
上一篇:深拷贝与浅拷贝


下一篇:JS深拷贝与浅拷贝