java对象流与序列化
2016-06-12 19:40
417 查看
对象序列化
Java语言有一种非常通用的对象序列化机制,它可以将任何对象写出到流中,并在之后将其读回。序列化:把Java对象转换为字节序列的过程。
反序列化:把字节序列恢复为Java对象的过程。
具体实例:
我们先创建一个学生对象:/*/
* 学生对象
*/
public class Student implements Serializable{
private String name;
private Integer age;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Student(String name, Integer age, String address) {
super();
this.name = name;
this.age = age;
this.address = address;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", address="
+ address + "]";
}
}
为了方便打印重写一下里面的toString()方法;
为了保存对象数据,首先需要打开一个objectOutputStream对象:
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("C:\\E盘\\Student.java"));接着使用writeObject方法:
Student student=new Student("张三", 23, "111");
out.writeObject(student);
然后再读取我们的这个对象:
ObjectInputStream in=new ObjectInputStream(new FileInputStream("C:\\E盘\\Student.java"));
System.out.println(in.readObject());这里要注意的是,在对象流中存储或恢复的所有类应进行修改,那么这些类必须实现Serializable接口;
实现java.io.Serializable 接口的类是可序列化的。没有实现此接口的类将不能使它们的任一状态被序列化或逆序列化。
序列化类的所有子类本身都是可序列化的。这个序列化接口没有任何方法和域,仅用于标识序列化的语意。允许非序列化类的子类型序列化,子类型可以假定负责保存和恢复父类型的公有的、保护的和(如果可访问)包的域的状态。只要该类(即父类)有一个无参构造子,可初始化它的状态,那么子类型就可承担上述职责;如果该类没有无参构造函数,在这种情况下申明一个可序列化的类是一个错误。此错误将在运行时被检测。
例如:Integer实现了Serializable,所以可以把一个Integer的对象用IO写到文件里,之后再可以从文件里读出,如你开始写入的时候那个对象的intValue() 是5的话,那读出来之后也是5。这一点体现了用序化类的作用,即用来传送类的对象。
特殊情况:
假如一个对象被多个对象共享,作为他们一部分时,会发生什么事情啦?我们创建一个老师类:
public class Teacher implements Serializable{
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public Teacher(Student student) {
super();
this.student = student;
}
@Override
public String toString() {
return "Teacher [student=" + student + "]";
}
}这里假设每个老师都有一个学生;
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("C:\\E盘\\teacher.java"));
Student student=new Student("张三", 23, "111");
Teacher teacher=new Teacher(student);
Teacher teacher2=new Teacher(student);
每个老师都包含一个学生对象的引用;在这里我们不能去保存和恢复学生对象的内存地址,因为当对象被重新加载时,它可能占据的是与原来完全不同的内存地址。
所以这里我们要为对象添加一个序列号保存;这种机制是对象序列化的原因所在,下面是其算法:
1.对你遇到的每一个对象引用都关联一个序列号;
2.对于每一个对象,当第一次遇到时,保存其对象数据到流中。
3.如果某个对象之前已经保存过,那么在写的时候,只会写出与之前保存过的序列号相同的对象;
4.对于流中的对象,在第一次遇到其序列号时,构建它,并使用流中数据来初始化它。然后记录这个序列号和新对象之间的关联;
5.当遇到与之前保存过的序列号的对象相同时,获取这个顺序号相关联的对象引用;
理解对象序列化的文件格式:
对象序列化是以特殊的文件格式存储对象数据的。比如 AC ED 后面紧跟着对象序列化格式的版本号00 05
当存储一个对象时,这个对象所属的类也必须存储。这个类的描述包含
1.类名。
2.序列化版本的唯一的ID serialVersionUID;
3.描述序列化方法的标志集。
4.对数据域的描述。
transient关键字:
如果我们不希望某些数据被序列化,可以使用transient关键字。他们会在对象序列化时被跳过;当然与序列化有关的还有克隆复制方法,这个下次总结;
相关文章推荐
- Struts2中获取session、request、respsonse的两种方法
- spring(11)使用对象-关系映射持久化数据
- 修改Struts2的struts.xml配置文件位置
- Eclipse 导入 Makefiles 项目
- Java(代码块)
- MySQL 5.7 java 运行 mysql.exe还原数据库兼容性问题
- myeclipse中创建struts2的web项目
- Javaworkers团队第五周项目总结
- [javaEE] response实现图片下载
- java用正则方法验证文件名是否合法
- 初学java制作了一个绘图板
- 字符数组转换为字符串
- jtable导出到excel
- spring常用的工具类
- jtable自适应列宽度
- Spring MVC 页面渲染( render view )
- JAVA——Properties中如何将流中的数据存储到集合中
- 《Java高级程序设计》期末作业【3】
- Java练习:牛顿迭代法 Vs. 不动点
- Spring配置文件中<context:include-filter>和<context:exclude-filter>