转载请注明出处,谢谢!
方法1:
1 /*jdk >= 1.5*/ 2 @SuppressWarnings("unchecked") 3 public static <T> T deepClone(T obj) { 4 T clonedObj = null; 5 ObjectOutputStream oos = null; 6 ObjectInputStream ois = null; 7 try { 8 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 9 oos = new ObjectOutputStream(baos); 10 oos.writeObject(obj); 11 ByteArrayInputStream bais = new ByteArrayInputStream( 12 baos.toByteArray()); 13 ois = new ObjectInputStream(bais); 14 clonedObj = (T) ois.readObject(); 15 } catch (Exception e) { 16 e.printStackTrace(); 17 } finally { 18 try { 19 oos.close(); 20 ois.close(); 21 } catch (IOException e) { 22 e.printStackTrace(); 23 } 24 25 } 26 return clonedObj; 27 }
方法2:
1 /*jdk >= 1.7*/ 2 @SuppressWarnings("unchecked") 3 public static <T> T deepCopy(T srcObj) { 4 T targetObj = null; 5 try 6 ( 7 ByteArrayInputStream bais = new ByteArrayInputStream(deepCopyRepo(srcObj, new ByteArrayOutputStream()).toByteArray()); 8 ObjectInputStream ois = new ObjectInputStream(bais) 9 ) 10 { 11 targetObj = (T) ois.readObject(); 12 } 13 catch (Exception e) 14 { 15 e.printStackTrace(); 16 } 17 return targetObj; 18 } 19 public static ByteArrayOutputStream deepCopyRepo(Object obj,ByteArrayOutputStream baos) throws Exception { 20 try 21 ( 22 ObjectOutputStream oos = new ObjectOutputStream(baos) 23 ) 24 { 25 oos.writeObject(obj); 26 } 27 return baos; 28 }
注意事项:
1.若Java 7 build 105 版本及以上,推荐使用方法2;try-with-resources语句,ARM(Automatic Resource Management) 自动资源管理。
2.被拷贝对象必须为可序列化的;当然,常用的如HashMap,ArrayList都是实现序列化的,直接使用本方法即可。
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
示例POJO:
1 import java.io.Serializable; 2 import java.util.List; 3 4 public class Person implements Serializable{ 5 /*自定义版本*/ 6 private static final long serialVersionUID = 1L; 7 8 private String name; 9 private List<Person> children; 10 /*age属性因transient修饰,所以被序列化机制隔离*/ 11 private transient int age; 12 public Person(String name,List<Person> children,int age){ 13 this.name = name; 14 this.children = children; 15 this.age = age; 16 } 17 public Person(){} 18 public String getName() { 19 return name; 20 } 21 public void setName(String name) { 22 this.name = name; 23 } 24 public List<Person> getChildren() { 25 return children; 26 } 27 public void setChildren(List<Person> children) { 28 this.children = children; 29 } 30 public int getAge() { 31 return age; 32 } 33 public void setAge(int age) { 34 this.age = age; 35 } 36 @Override/*根据jvm返回的hashCode判断对象相同*/ 37 public String toString() { 38 return "Person"+ "@" + Integer.toHexString(this.hashCode())+" [name=" + name + ", children=" + children + ", age=" 39 + age + "]"; 40 } 41 }
junit:
1 @Test 2 public void testDeepCopy(){ 3 List<Person> children = new ArrayList<>(); 4 Person daughter = new Person("daughter",null,3); 5 Person son = new Person("son",null,1); 6 children.add(son);children.add(daughter); 7 Person father = new Person("sqiang",children,29); 8 System.out.println(father); 9 Person cfather = Utils.deepCopy(father); 10 System.out.println(cfather); 11 }
Console:
如图所示:
1.两组对象均不相同,实现了深拷贝
2.第二组的age=0,transient关键字对序列化起了作用。