1.什么是序列化?
序列化就是一种用来处理对象流的机制。(所谓的对象流也就是将对象内容进行流化,流也就是I/O(I/O是什么就不多说了))
我们可以将流化的对象进行读写操作,也可以将流化后的对象在网络之间传输(注:要想将对象传输于网络必须进行流化)!
但是在对对象流进行一些读写操作时会引发一些问题,而序列化这个机制正式用来解决这个问题的。
2.引发问题的原因:
综上所述,读写对象是会引发什么问题呢?
比如:我把一个对象写入磁盘中,然后立刻将它读取出来会出现什么问题呢?
打个比方:我创建了两个类,分别是A和B,在B类中有一个指向A类的对象,然后给两个类进行实例化,在这个时候内存中实际上分配了两个空间,一个存储对象a,一个存储对象b,让后我们把它们写入到磁盘的一个文件中去,这时候就出现了问题,因为在B类中包含了一个A类的对象,想一下两个内存空间一个A类的一个B类的,应为在B类中一个A类的对象,所以在B类写入的时候自动把A类copy了一份,这下就等于有了三个内存空间,而且有两个都是A类的内存空间,那么是肯定会出问题的,如果我以后想要去修改A类的内容,那是不是还要把每一个它的拷贝都去修改一下,这个肯定是我们不希望看到的。
3.解决方法:
1.保存到磁盘的所有对象都获得一个序列号(1, 2, 3等等)
2.当要保存一个对象时,先检查该对象是否被保存了
3.如果以前保存过,只需写入”与已经保存的具有序列号x的对象相同”的标记,否则,保存该对象
通过以上的步骤序列化机制解决了对象引用的问题!
四、序列化的实现
将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable
只是为了标注该对象是可被序列化的。然后使用一个输出流(如:FileOutputStream)来构造一个
ObjectOutputStream(对象流)对象。接着,使用ObjectOutputStream对象的writeObject(Object obj)方法
就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
在序列化的过程中,有些数据字段我们不想将其序列化,对于此类字段我们只需要在定义
时给它加上transient关键字即可,对于transient字段序列化机制会跳过不会将其写入文件,当然
也不可被恢复。但有时我们想将某一字段序列化,但它在SDK中的定义却是不可序列化的类型,
这样的话我们也必须把他标注为transient,可是不能写入又怎么恢复呢?好在序列化机制为包含
这种特殊问题的类提供了如下的方法定义:
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
private void writeObject(ObjectOutputStream out) throws IOException;