对象深度拷贝
利用序列化与反序列化对对象进行深度复制
Java代码
1. public class Student implements Serializable {
2.
3. private String name;
4. private String tel;
5. private int age;
6.
7. //set and get.....
8. }
9.
10. public class Teacher implements Serializable {
11.
12. private String name;
13. private int age;
14. private List<Student> stuList;
15.
16. //set and get....
17.
18. }
19.
20. import java.io.ByteArrayInputStream;
21. import java.io.ByteArrayOutputStream;
22. import java.io.IOException;
23. import java.io.ObjectInputStream;
24. import java.io.ObjectOutputStream;
25. import java.util.ArrayList;
26. import java.util.List;
27.
28. public class Test {
29.
30.
31. public static void main(String[] args) {
32. Student s1 = new Student();
33. s1.setName("Wang");
34. s1.setAge(25);
35. s1.setTel("110");
36. Student s2 = new Student();
37. s2.setName("Li");
38. s2.setAge(35);
39. s2.setTel("119");
40.
41.
42. Teacher t = new Teacher();
43. t.setName("Zhang");
44. t.setAge(50);
45. List<Student> stuList = new ArrayList<Student>();
46. stuList.add(s1);
47. stuList.add(s2);
48. t.setStuList(stuList);
49. System.out.println("t: "+t);
50. System.out.println("s1: "+s1);
51. System.out.println("s2: "+s2);
52. System.out.println("after clone--------------");
53. Teacher t2 = (Teacher) depthClone(t);
54. System.out.println("t2: "+t2);
55. System.out.println("t: "+t);
56.
57. Student s3 = t2.getStuList().get(0);
58. Student s4 = t2.getStuList().get(1);
59. System.out.println("s3: "+s3);
60. System.out.println("s1: "+s1);
61. System.out.println("s4: "+s4);
62. System.out.println("s2: "+s2);
63.
64. System.out.println("after change--------------");
65. t2.setAge(55);
66. t2.setName("Zhao");
67.
68. System.out.println("t2 Name: "+t2.getName()+" t2 age"+t2.getAge());
69. System.out.println("t Name: "+t.getName()+" t age"+t.getAge());
70.
71. }
72.
73. private static Object depthClone(Object srcObj){
74. Object cloneObj = null;
75. try {
76. ByteArrayOutputStream out = new ByteArrayOutputStream();
77. ObjectOutputStream oo = new ObjectOutputStream(out);
78. oo.writeObject(srcObj);
79.
80. ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
81. ObjectInputStream oi = new ObjectInputStream(in);
82. cloneObj = oi.readObject();
83. } catch (IOException e) {
84. e.printStackTrace();
85. } catch (ClassNotFoundException e) {
86. e.printStackTrace();
87. }
88. return cloneObj;
89. }
90.
91. }
public class Student implements Serializable {
private String name;
private String tel;
private int age;
//set and get.....
}
public class Teacher implements Serializable {
private String name;
private int age;
private List<Student> stuList;
//set and get....
}
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("Wang");
s1.setAge(25);
s1.setTel("110");
Student s2 = new Student();
s2.setName("Li");
s2.setAge(35);
s2.setTel("119");
Teacher t = new Teacher();
t.setName("Zhang");
t.setAge(50);
List<Student> stuList = new ArrayList<Student>();
stuList.add(s1);
stuList.add(s2);
t.setStuList(stuList);
System.out.println("t: "+t);
System.out.println("s1: "+s1);
System.out.println("s2: "+s2);
System.out.println("after clone--------------");
Teacher t2 = (Teacher) depthClone(t);
System.out.println("t2: "+t2);
System.out.println("t: "+t);
Student s3 = t2.getStuList().get(0);
Student s4 = t2.getStuList().get(1);
System.out.println("s3: "+s3);
System.out.println("s1: "+s1);
System.out.println("s4: "+s4);
System.out.println("s2: "+s2);
System.out.println("after change--------------");
t2.setAge(55);
t2.setName("Zhao");
System.out.println("t2 Name: "+t2.getName()+" t2 age"+t2.getAge());
System.out.println("t Name: "+t.getName()+" t age"+t.getAge());
}
private static Object depthClone(Object srcObj){
Object cloneObj = null;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(out);
oo.writeObject(srcObj);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream oi = new ObjectInputStream(in);
cloneObj = oi.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return cloneObj;
}
}
输入结果:
t: jame.jsp.bean.Teacher@affc70
s1: jame.jsp.bean.Student@1e63e3d
s2: jame.jsp.bean.Student@1004901
after clone--------------
t2: jame.jsp.bean.Teacher@1f14ceb
t: jame.jsp.bean.Teacher@affc70
s3: jame.jsp.bean.Student@f0eed6
s1: jame.jsp.bean.Student@1e63e3d
s4: jame.jsp.bean.Student@1d05c81
s2: jame.jsp.bean.Student@1004901
after change--------------
t2 Name: Zhao t2 age55
t Name: Zhang t age50
*采用些方法做深度拷贝时,要求所有对象implements Serializable,否则报java.io.NotSerializableException异常。
分享到:
相关推荐
在实际应用中,我们还可以考虑使用序列化和反序列化的方式实现深度拷贝,或者使用第三方库如Apache Commons Lang的`DeepClone`方法,它们提供了更简便的解决方案。但这里我们重点讨论了如何仅通过Java反射机制来实现...
首先,我们需要确保待拷贝的对象是可序列化的,因为Java的序列化机制可以用来实现深度拷贝。在Java中,一个类如果要支持序列化,需要实现`java.io.Serializable`接口。例如,`Student`类就是一个可序列化的类: ```...
总的来说,Java序列化提供了一种实现对象深度克隆的方法,适用于需要完整复制对象及其关联对象的情况。然而,这也带来了一些潜在问题,如性能影响、安全风险(因为序列化的对象可能被恶意用户反序列化以执行代码)...
这种方法利用Java的序列化机制实现深度克隆。具体步骤如下: 1. **实现Serializable接口**:需要被克隆的类必须实现`Serializable`接口。 2. **序列化对象**:将对象转换为字节流。 3. **反序列化对象**:从字节流...
4. **序列化配置**:Kryo提供了丰富的配置选项,如注册特定的序列化策略,控制序列化深度,以及选择是否保留对象的类信息等。 5. **兼容性**:尽管Kryo不是Java标准的序列化机制,但它可以与Java原生的序列化系统...
Kryo是一个针对Java的高性能对象图序列化框架,由Esoteric Software开发,其特性包括快速、高效以及自动处理,使得在内存序列化和反序列化过程中能实现卓越的性能。 **Kryo的核心特性** 1. **速度与效率**:Kryo...
深复制通常需要自定义实现,或者利用序列化和反序列化的方法来完成。例如: ```java public MySerializableClass deepCopy() throws IOException, ClassNotFoundException { ByteArrayOutputStream ...
- **序列化与反序列化**:将对象序列化为字节数组,然后再反序列化为新的对象,实现深拷贝。 3. **注解实现对象复制** - **Apache Commons BeanUtils库**:提供了`BeanUtils.copyProperties()`方法,可以快速实现...
1. **实现Serializable接口**:利用序列化和反序列化来实现深拷贝。首先将对象序列化为字节数组,然后再将这个字节数组反序列化为新的对象。这种方法适用于所有实现了Serializable接口的对象,但效率较低,并且如果...
总的来说,这个研究关注的是如何利用先进的硬件技术和定制化的序列化策略来优化Java对象在网络传输中的性能,尤其是针对大数据处理和分布式计算环境。通过堆直写和特定的序列化工具,可以显著减少序列化和反序列化...
3. **深度复制**:Kryo不仅支持基本的序列化和反序列化,还能实现对象的深拷贝,这对于数据备份、状态恢复等场景非常有用。 4. **预注册类**:预先注册要序列化的类可以进一步提升性能,因为Kryo在运行时无需动态...
对于复杂对象,可以利用Java的序列化机制进行深拷贝。将对象序列化为字节流,然后反序列化得到一个新的独立对象。这种方式适用于那些不支持`Cloneable`接口或`clone()`方法的对象。 9. **数据复制在大数据中的应用...
- **序列化与反序列化**:在对象序列化时,可能需要获取对象的所有字段,反射可以实现这一点。 - **框架开发**:许多框架如Spring、Struts等使用反射来实现依赖注入,动态调用方法。 - **动态代理**:Java的动态代理...
在Java中,可以利用序列化和反序列化实现深拷贝: ```java public Object deepClone() { try { ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo);...
这种方法在处理复杂对象结构或需要解耦代码时特别有用,例如在数据持久化、对象拷贝或者JSON序列化与反序列化等场景。 当然,使用反射会带来性能上的开销,且可能会增加代码的复杂性。因此,在实际开发中,我们通常...
通过研究源码,开发者可以深入了解其内部实现,定制自己的序列化解决方案,或者为项目贡献代码。 总的来说,FlatBuffers是一种强大的序列化工具,它通过优化内存布局和访问方式,提供了高效的序列化和反序列化体验...
枚举单例是Java中最安全且防止反序列化重新创建单例的方法。 3. **NIO、BIO、AIO**:Java的非阻塞I/O(NIO)提供了异步I/O能力,比传统的阻塞I/O(BIO)更高效,因为它允许一个线程处理多个通道。AIO(Async I/O)...
- **普通类**: 必须实现所有抽象方法才能被实例化。 **13. 抽象类能使用`final`修饰吗?** - 不能。`abstract`和`final`是相互排斥的,因为`abstract`允许类未完成实现而`final`不允许子类覆盖父类的方法。 **14....
10. **对象工具**:提供了对象的比较、克隆、序列化、深度拷贝等操作。 总的来说,Apache Commons Lang是一个非常实用的Java开发库,它通过提供大量的工具类和方法,能够帮助开发者更加高效地处理常见的编程任务,...