美文网首页
Java-序列化 —(二)

Java-序列化 —(二)

作者: Sandy_678f | 来源:发表于2018-12-01 15:15 被阅读0次

如果一个类不仅实现了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<size; i++) {
            s.writeObject(elementData[i]);
        }

        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }

   private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        elementData = EMPTY_ELEMENTDATA;

        // Read in size, and any hidden stuff
        s.defaultReadObject();

        // Read in capacity
        s.readInt(); // ignored

        if (size > 0) {
            // be like clone(), allocate array based upon size not capacity
            int capacity = calculateCapacity(elementData, size);
            SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);
            ensureCapacityInternal(size);

            Object[] a = elementData;
            // Read in all elements in the proper order.
            for (int i=0; i<size; i++) {
                a[i] = s.readObject();
            }
        }

那么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-序列化 —(二)

    如果一个类不仅实现了Serializable接口,而且定义了 readObject(ObjectInputStre...

  • JAVA-线程-一-执行器Executor

    2. JAVA-线程-二-ExecutorService 接口 3. JAVA-线程-三-AbstractExec...

  • JAVA-线程-三-AbstractExecutorServic

    1. JAVA-线程-一-执行器Executor 2. JAVA-线程-二-ExecutorService 接口 ...

  • Java-序列化

    序列化:将数据结构或者对象转换成二进制串的过程。 反序列化:将序列化生成的二进制串转换成数据结构或者对象的过程 应...

  • Hello Java

    目录 Java-基础(1/6) Java-对象(2/6) Java-核心库类 上(3/6) Java-核心库类下(...

  • Java-序列化-反序列化

    Thanks Java基础学习总结——Java对象的序列化和反序列化java序列化反序列化原理Java 序列化的高...

  • Java-序列化 —(一)

    1、什么是序列化与反序列化 2、为什么要序列化 3、Java 怎么进行序列化? 1、不需要序列化的字段用trans...

  • Effective Java-序列化

    Java序列化机制提供了一个框架,用来将对象编码成字节流,并从字节流编码中重新构建对象。一旦对象被序列化之后,就可...

  • Effective Java-序列化

    谨慎地实现Serializable接口 考虑使用自定义的序列化形式 保护性地编写readObject方法 对于实例...

  • Java-浅析Object类

    Java-浅析Object类 ++2016.7.19++byside @Java-浅析Object类 ======...

网友评论

      本文标题:Java-序列化 —(二)

      本文链接:https://www.haomeiwen.com/subject/gofrcqtx.html