Java-序列化 —(二)

如果一个类不仅实现了Serializable接口,而且定义了 readObject(ObjectInputStream in)和 writeObject(ObjectOutputStream out)方法,那么将按照如下的方式进行序列化和反序列化:

ObjectOutputStream会调用这个类的writeObject方法进行序列化,ObjectInputStream会调用相应的readObject方法进行反序列化。

例:ArrayList集合类。其中elementData用transient修饰,不需要进行序列化。ArrayList自身实现了writeObject和readObject方法。

ArrayList源码

    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
        // Write out element count, and any hidden stuff
        int expectedModCount = modCount;
        s.defaultWriteObject();

        // Write out size as capacity for behavioural compatibility with clone()
        s.writeInt(size);

        // Write out all elements in the proper order.
        for (int i=0; i

那么ObjectOutputStream又是如何知道一个类是否实现了writeObject方法呢?又是如何自动调用该类的writeObject方法呢?
是通过反射机制实现的。

ObjectOutputStream的writeObject会根据传进来的ArrayList对象得到Class,然后再包装成 ObjectStreamClass,在writeSerialData方法里,会调用ObjectStreamClass的 invokeWriteObject方法。

注意:s.defaultReadObject()函数在defaultReadObject()函数前执行。
作用:
1、It reads and writes all the non transient fields of the class respectively.

2、 These methods also helps in backward and future compatibility. If in future you add some non-transient field to the class and you are trying to deserialize it by the older version of class then the defaultReadObject() method will neglect the newly added field, similarly if you deserialize the old serialized object by the new version then the new non transient field will take default value from JVM

/**
 * FileName: ArrayListTest
 * Author:   Sandy
 * Date:     2018/12/1 14:25
 * Description:
 * Version: v1.0.0
 */

package AggregationDemo;

import java.io.*;
import java.util.ArrayList;

public class ArrayListTest {

    public static void main(String[] args) throws IOException, ClassNotFoundException {

            ArrayList arrayList = new ArrayList();

            arrayList.add(1);
            arrayList.add("123");


            System.out.println("1. 原始对象:" + arrayList);

            //ArrayList序列化
            ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("ArrayListTest"));
            outputStream.writeObject(arrayList);

            //反序列化
            ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("ArrayListTest"));
            ArrayList arrayList_other = (ArrayList) inputStream.readObject();

            arrayList.add(123.312);
            arrayList_other.add("abc");

            System.out.println("2. 原始对象:" + arrayList);
            System.out.println("3. 拷贝对象:" + arrayList_other);
    }

}

输出

1. 原始对象:[1, 123]
2. 原始对象:[1, 123, 123.312]
3. 拷贝对象:[1, 123, abc]

你可能感兴趣的:(Java-序列化 —(二))