定义
对象序列化,就是将Object转换成byte序列,反之叫对象的反序列化.
- 序列化流(
ObjectOutputStream
),是过滤流—-writeObject
- 反序列化流(
ObjectInputStream
)—-readObject
序列化接口(Serializable)
对象必须实现序列化接口 ,才能进行序列化,否则将出现异常
这个接口,没有任何方法,只是一个标准.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| String file = "demo/obj.dat"; ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(file)); Student stu = new Student("10001", "张三", 20); oos.writeObject(stu); oos.flush(); oos.close(); ObjectInputStream ois = new ObjectInputStream( new FileInputStream(file)); Student stu = (Student)ois.readObject(); System.out.println(stu); ois.close();
|
transient关键字
transient
修饰的变量不会进行jvm默认的序列化,但可以自己完成这个元素的序列化.即覆写:
1 2 3 4
| private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| public class Student implements Serializable{ private String stuno; private String stuname; private transient int stuage; public Student(String stuno, String stuname, int stuage) { super(); this.stuno = stuno; this.stuname = stuname; this.stuage = stuage; }
public String getStuno() { return stuno; } public void setStuno(String stuno) { this.stuno = stuno; } public String getStuname() { return stuname; } public void setStuname(String stuname) { this.stuname = stuname; } public int getStuage() { return stuage; } public void setStuage(int stuage) { this.stuage = stuage; } @Override public String toString() { return "Student [stuno=" + stuno + ", stuname=" + stuname + ", stuage=" + stuage + "]"; } private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ s.defaultWriteObject(); s.writeInt(stuage); } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException{ s.defaultReadObject(); this.stuage = s.readInt(); } }
|
如ArrayList
源码中对elementData
数组序列化和反序列化的处理,因为elementData
数组中不是所有元素都是有效元素,所以只序列化了size
个有效元素.


序列化中 子父类构造函数的调用问题
一个类实现了序列化接口,那么其子类都可以进行序列化.
对子类对象进行反序列化操作时,如果其父类没有实现序列化接口,那么其父类的构造函数会被调用.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| public class ObjectSeriaDemo2 { public static void main(String[] args) throws Exception{ ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("demo/obj1.dat")); Foo2 foo2 = new Foo2(); oos.writeObject(foo2); oos.flush(); oos.close(); ObjectInputStream ois = new ObjectInputStream( new FileInputStream("demo/obj1.dat")); Foo2 foo2 = (Foo2)ois.readObject(); System.out.println(foo2); ois.close(); ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("demo/obj1.dat")); Bar2 bar2 = new Bar2(); oos.writeObject(bar2); oos.flush(); oos.close();
ObjectInputStream ois = new ObjectInputStream( new FileInputStream("demo/obj1.dat")); Bar2 bar2 = (Bar2)ois.readObject(); System.out.println(bar2); ois.close();
} }
class Foo implements Serializable{ public Foo(){ System.out.println("foo..."); } } class Foo1 extends Foo{ public Foo1(){ System.out.println("foo1..."); } } class Foo2 extends Foo1{ public Foo2(){ System.out.println("foo2..."); } } class Bar{ public Bar(){ System.out.println("bar"); } } class Bar1 extends Bar{ public Bar1(){ System.out.println("bar1.."); } } class Bar2 extends Bar1 implements Serializable{ public Bar2(){ System.out.println("bar2..."); } }
|