对象的序列化和反序列化
对象序列化,就是将Object转换成byte序列,反之叫对象的反序列化
序列化基本操作
序列化接口(serializable)
对象必须实现序列化接口,才能进行序列化,否则将出现异常
这个接口,没有任何方法,只是一个标准
ObjectOutputStream/ObjectInputStream
序列化流(ObjectOutputStream),是过滤流—-writeobject
反序列化流(ObjectInputStream)—readObject
transient
属性成员用transient修饰,表示该元素不会进行jvm默认的序列化,但是可以手动完成这个元素的序列化,通过分析ArrayList源码,通过下面两个函数进行手动序列化和反序列化
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException
这样对 transient修饰的elementData成员,进行优化。
序列化中子父类构造函数问题
- 一个类实现了序列化接口,那么其子类都可以进行序列化
- 对子类对象进行反序列化操作时,如果其父类没有实现 序列化接口,那么其父类的构造函数会被调用
代码
public class Student {
private String stuName;
private String stuNo;
/*
* transient修饰 该元素不会进行jvm默认的序列化,
* 但是可以手动完成这个元素的序列化
*/
private transient int stuAge;
public Student() {
super();
}
public Student(String stuName, String stuNo, int stuAge) {
super();
this.stuName = stuName;
this.stuNo = stuNo;
this.stuAge = stuAge;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public String getStuNo() {
return stuNo;
}
public void setStuNo(String stuNo) {
this.stuNo = stuNo;
}
public int getStuAge() {
return stuAge;
}
public void setStuAge(int stuAge) {
this.stuAge = stuAge;
}
@Override
public String toString() {
return "Student [stuName=" + stuName + ", stuNo=" + stuNo + ", stuAge="
+ stuAge + "]";
}
/*
* 进行序列化,参考ArrayList
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
s.defaultWriteObject(); //把jvm能默认序列化的元素进行序列化操作
s.writeInt(stuAge);//手动完成stuAge的序列化
}
/*
* 进行反序列化,参考ArrayList
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException{
s.defaultReadObject(); //把jvm默认反序列化的元素进行反序列化操作
this.stuAge = s.readInt(); //手动进行反序列化
}
}