说到对象的复制或者克隆,大家可能会想到一下几种工具类:
1、BO克隆:BeanUtils.copyProperties(srcObj,destObj) spring框架提供的工具类,第一个参数源数据,第二个 参数目标对象。注意源对象和目标对象中的属性名和属性类型必须完全一致,才能进行复制;该方法主要用于复制bo等
2、List克隆:Collections.copy(destList,srcList) 来自于java.util.Collections。第一个参数是目标对象,第二个参数是源对象,正好 beanUtils.copyProperties()相反,该方法可以用于复制list,在使用时,destList必须进行初始化容量
例如:List<String> dic = new ArrayList<String>(Arrays.asList(new String[src.size()]))
错误的初始化:List<String> dst = new ArrayList<String>(src.size());因为这是设定集合是容量是多大,而不是初始化集合。
本示例中采用ParentClass 、SubClass的结构在下面的例子的贴出来了。 public static void main(String [] args){ ParentClass parentClass = new ParentClass(); SubClass sub1 = new SubClass(); sub1.setSubAge(11); sub1.setSubName("sub11"); SubClass sub2 = new SubClass(); sub2.setSubName("sub22"); sub2.setSubAge(22); SubClass sub3 = new SubClass(); sub3.setSubName("sub33"); sub3.setSubAge(33); List<SubClass> list = new ArrayList(); list.add(sub1); list.add(sub2); parentClass.setList(list); parentClass.setSubClass(sub3); parentClass.setFatherName("fatherName"); parentClass.setFatherAge(88); List<ParentClass> srcList = new ArrayList<>(); srcList.add(parentClass); List<ParentClass> destList = new ArrayList(Arrays.asList(new String[srcList.size()])); Collections.copy(destList, srcList); }
但是还有一种方法采用深度克隆,实现代码如下:
/** * 该方法适用于复杂对象的深度克隆 * @param srcObj 源对象 * @return Object 目标对象 * @throws Exception */ static Object deepClone(Serializable srcObj) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(out); oo.writeObject(srcObj); ByteArrayInputStream in = new ByteArrayInputStream(out .toByteArray()); ObjectInputStream oi = new ObjectInputStream(in); return oi.readObject(); }
该方法使用需注意:参数 srcObj 必须实现了序列化接口
Serializable,这个方法最大的好处是,不管srcObj内部属性多么复杂,嵌套层级多大,都可以进行深度克隆。
测试示例如下:
BO1:
public class SubClass implements Serializable { private static final long serialVersionUID = 3232707926247447408L; private String subName; private int subAge; .....setter/getter方法省略.... }
BO2: public class ParentClass implements Serializable { private static final long serialVersionUID = -3556157995320461937L; private String fatherName; private int fatherAge; private List<SubClass> list; private SubClass subClass; .....setter/getter方法省略.... }
测试:
public class MyTest { /** * * @param srcObj 源对象 * @return Object 目标对象 * @throws Exception */ static Object deepClone(Serializable srcObj) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(out); oo.writeObject(srcObj); ByteArrayInputStream in = new ByteArrayInputStream(out .toByteArray()); ObjectInputStream oi = new ObjectInputStream(in); return oi.readObject(); } public static void main(String [] args){ ParentClass parentClass = new ParentClass(); SubClass sub1 = new SubClass(); sub1.setSubAge(11); sub1.setSubName("aaa11"); SubClass sub2 = new SubClass(); sub2.setSubName("bbb22"); sub2.setSubAge(22); SubClass sub3 = new SubClass(); sub3.setSubName("ccc33"); sub3.setSubAge(33); List<SubClass> list = new ArrayList(); list.add(sub1); list.add(sub2); parentClass.setList(list); parentClass.setSubClass(sub3); try { Object obj = deepClone(parentClass); } catch (Exception e) { System.err.println("EXECPTION=" + e.getMessage()); } }
}