当前位置: 代码迷 >> J2SE >> 源码分析:ArrayList的writeobject步骤中的实现是否多此一举
  详细解决方案

源码分析:ArrayList的writeobject步骤中的实现是否多此一举

热度:62   发布时间:2016-04-23 20:03:53.0
源码分析:ArrayList的writeobject方法中的实现是否多此一举?
本帖最后由 ainibc 于 2014-11-27 21:45:06 编辑
问题描述:jdk1.7中的ArrayList源码,size并非transient,所以s.defaultWriteObject();方法已经把size写入序列流,s.writeInt(size);再重复地写一次size意义何在?这不是多次一举吗?恳请各位指点迷津。
部分关键源码:
字段声明

/**
     * The size of the ArrayList (the number of elements it contains).
     */
    private int size;

写方法:

private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
        int expectedModCount = modCount;
        s.defaultWriteObject();

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

        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.IOExceptionClassNotFoundException {
        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
            ensureCapacityInternal(size);

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

------解决思路----------------------
defaultReadObject() and defaultWriteObject() should be the first method call inside readObject(ObjectInputStream o) and writeObject(ObjectOutputStream o). It reads and writes all the non transient fields of the class respectively. 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 i.e. if its object then null else if primitive then boolean to false, int to 0 etc….
解释的很清楚了。
  相关解决方案