Java串行化深度复制与性能调优
来源:互联网 发布:windows有王者荣耀吗 编辑:程序博客网 时间:2024/05/24 00:28
关于java的浅度复制与深度复制的概念大家可以在许多博文中找到
我们直接上代码,看一下浅度复制的一个例子:
这里有三个类College,Teacher,Student
College类
public class College { private String name; public College(){ } public College(String name) { super(); this.name = name; } //setter/getter ...}Teacher类
public class Teacher { private String name; private Integer age; private College college; private List<Student> students; public Teacher() { } public Teacher(String name, Integer age) { super(); this.name = name; this.age = age; } //setter/getter ...}
Student类
public class Student { private String name; private Integer age; private String className; public Student() { } public Student(String name, Integer age, String className) { super(); this.name = name; this.age = age; this.className = className; } //setter/getter ...}
测试类
public class TestClone { @Test public void testShallowClone() { College college1 = new College("ACollege"); Teacher teacher1 = new Teacher("ATeacher", 32); Student student1 = new Student("AStudent1", 14, "1-A"); Student student2 = new Student("AStudent2", 15, "1-A"); List<Student> students = Arrays.asList(student1,student2); teacher1.setCollege(college1); teacher1.setStudents(students); //浅度复制一个例子,这里可以用Colne()代替 Teacher teacher2 = new Teacher(teacher1.getName(),teacher1.getAge()); teacher2.setCollege(teacher1.getCollege()); teacher2.setStudents(teacher1.getStudents()); System.out.println(teacher1); System.out.println(teacher2); System.out.println(teacher1.getCollege()); System.out.println(teacher2.getCollege()); }}
运行结果为
com.clone.Teacher@238e0d81
com.clone.Teacher@31221be2
com.clone.College@377dca04
com.clone.College@377dca04
简单学过java的人都应该知道这个结果,这就时浅度复制的一个例子,它只能复制一个对象,这两个对象只是内存地址不同,其他的都相同,包括引用类型的属性,他们都指向同一个引用。用一下对象图表示
然而如果我们要得到以下效果该如何呢
这里提供一个串行化的解决方案
关于什么时串行化(序列化)与反串行化(反序列化)这里不再敖述。
需要对类作如下修改
College类
public class College implements Serializable{ private static final long serialVersionUID = 1590896985634442223L; private String name; public College(){ } public College(String name) { super(); this.name = name; } //setter/getter ...}Teacher类
public class Teacher { private static final long serialVersionUID = -5667751032495765380L; private String name; private Integer age; private College college; private List<Student> students; public Teacher() { } public Teacher(String name, Integer age) { super(); this.name = name; this.age = age; } //setter/getter ...}Student类
public class Student implements Serializable { private static final long serialVersionUID = -4445065573351962915L; private String name; private Integer age; private String className; public Student() { } public Student(String name, Integer age, String className) { super(); this.name = name; this.age = age; this.className = className; } //setter/getter ...}进行深度复制的代码需要进行将对象转化为字节流与将字节流转化为对象的操作:
@Test public void testDeepClone() { College college1 = new College("ACollege"); Teacher teacher1 = new Teacher("ATeacher", 32); Student student1 = new Student("AStudent1", 14, "1-A"); Student student2 = new Student("AStudent2", 15, "1-A"); List<Student> students = Arrays.asList(student1,student2); teacher1.setCollege(college1); teacher1.setStudents(students); //将对象转化为字节流 ByteArrayOutputStream baos = null; ObjectOutputStream oos = null; ByteArrayInputStream bais = null; ObjectInputStream ois = null; try { baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(baos); oos.writeObject(teacher1); byte []buf = baos.toByteArray(); bais = new ByteArrayInputStream(buf); ois = new ObjectInputStream(bais); Teacher teacher2 = (Teacher) ois.readObject(); System.out.println(teacher1); System.out.println(teacher2); System.out.println(teacher1.getCollege()); System.out.println(teacher2.getCollege()); } catch (Exception e) { e.printStackTrace(); } finally { if (ois != null) { try { ois.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (bais != null) { try { bais.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (oos != null) { try { oos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(baos != null) { try { baos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
得出的结果为
com.clone.Teacher@246b179d
com.clone.Teacher@6e5e91e4
com.clone.College@b81eda8
com.clone.College@2cdf8d8a
这样就达到深度复制的效果了
在测试中我们会发现这样一个问题,如果在College没有实现Serializable接口,在进行深度复制时会报一个这样的一个异常:java.io.NotSerializableException,所在对象未序列化异常
可以想象以下,如果College里有一个List<Teacher>对象,那么在保证teacher1正常复制的情况下,会序列化一个庞大的对象网络,
一个学校有多名老师,一个老师有多名学生。。。为了达到复制一个老师信息的效果,结果把整个学校的信息全序列化了,这样时非常糟糕的,而且没有必要,十分浪费资源且性能太低。这时候我们就需要用到关键字transient,临时的。使用transient关键子修饰的对象将不再维护序列化机制,最后复制下来的时students,而college将会使null,这个值需要我们令行设置
- Java串行化深度复制与性能调优
- Java序列化与Java串行化
- Java集合对象的深度复制与普通复制
- java 深度复制与浅度复制的研究
- java深度复制
- java集合深度复制
- Java 实现深度复制
- java 深度复制
- C# 串行化与反串行化
- C# 串行化与反串行化
- 文档与串行化
- 文档与串行化
- 文档与串行化
- 文件与串行化
- 关于Java对象复制(Clone、深度Clone以及序列化与反序列化的使用)
- java对象串行化
- java串行化 转
- Java串行化问题
- Unity5混音器DSP插件编写教程【一】
- hdoj.4165 Pills【卡特兰数列】 2015/08/27
- 浏览器加载渲染网页过程解析
- textarea和mysql中的换行符问题
- Java String对象的经典问题(new String())
- Java串行化深度复制与性能调优
- The Euler function HDU杭电2824 【欧拉函数打表】
- SpringMVC总结
- Euro Efficiency 1252 (正负完全背包 好题)
- hdu 1203 I NEED A OFFER! <背包的变形>
- vs2012如何更改输出目录
- Objective-C语法之NSSet和NSMutableSet
- Eclipse Android SDK content Loader
- git