如何利用序列化来完成对象的拷贝呢?在内存中通过字节流的拷贝是比较容易实现的。把母对象写入到一个字节流中, 再从字节流中将其读出来, 这样就可以创建一个新的对象了, 并且该新对象与母对象之间并不存在引用共享的问题, 真正实现对象的深拷贝。
样例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class CloneUtils { @SuppressWarnings("unchecked") public static <T extends Serializable> T clone(T obj){ T cloneObj = null; try { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream obs = new ObjectOutputStream(out); obs.writeObject(obj); obs.close(); ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray()); ObjectInputStream ois = new ObjectInputStream(ios); cloneObj = (T) ois.readObject(); ois.close(); } catch (Exception e) { e.printStackTrace(); } return cloneObj; } }
|
使用该工具类的对象必须要实现 Serializable 接口, 否则是没有办法实现克隆的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Person implements Serializable{ private static final long serialVersionUID = 2631590509760908280L;
..................
}
public class Email implements Serializable{ private static final long serialVersionUID = 1267293988171991494L;
.................... }
|
所以使用该工具类的对象只要实现 Serializable 接口就可实现对象的克隆, 无须继承 Cloneable 接口实现 clone() 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Client { public static void main(String[] args) { Email email = new Email("请参加会议","请与今天12:30到二会议室参加会议...");
Person person1 = new Person("张三",email);
Person person2 = CloneUtils.clone(person1); person2.setName("李四"); Person person3 = CloneUtils.clone(person1); person3.setName("王五"); person1.getEmail().setContent("请与今天12:00到二会议室参加会议...");
System.out.println(person1.getName() + "的邮件内容是:" + person1.getEmail().getContent()); System.out.println(person2.getName() + "的邮件内容是:" + person2.getEmail().getContent()); System.out.println(person3.getName() + "的邮件内容是:" + person3.getEmail().getContent()); } } ------------------- Output: 张三的邮件内容是:请与今天12:00到二会议室参加会议... 李四的邮件内容是:请与今天12:30到二会议室参加会议... 王五的邮件内容是:请与今天12:30到二会议室参加会议...
|
在 JavaScript 中, 使用 JSON.parse/JSON.stringify
的方式实现:
1
| let cloned = JSON.parse(JSON.stringify(objectToClone));
|