首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Java

[ Java ]ArrayList 里面 elementData 为什么要设成 transient

  •  1
     
  •   MaxStack · 19 天前 · 434 次点击

    看了下 ArrayList 的源码

        /**
        * The array buffer into which the elements of the ArrayList are stored.
        * The capacity of the ArrayList is the length of this array buffer. Any
        * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
        * will be expanded to DEFAULT_CAPACITY when the first element is added.
        */
        transient Object[] elementData; // non-private to simplify nested class access
    

    看到 elementData 是 transient 的,于是又去看了下序列化的实现。

        /**
         * Save the state of the <tt>ArrayList</tt> instance to a stream (that
         * is, serialize it).
         *
         * @serialData The length of the array backing the <tt>ArrayList</tt>
         *             instance is emitted (int), followed by all of its elements
         *             (each an <tt>Object</tt>) in the proper order.
         */
        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();
            }
        }
    

    我觉得这里没有必要把 elementData 设成 transient,然后再一个一个遍历输出。直接用 defaultWriteObject 把 elementData 输出就可以了。

    我自己写了个 Dummy 的 ArrayList 测试,是可以直接序列化+反序列化数组的。

    求大神指点。

        1
    wdmx007   19 天前
    你看源码里面有类似于 fast-fail 的检查, 和 iterator.remove 类似,
    当有其他线程修改这个数组时,能保证序列化最终写入的数组内容与开始调用这个函数时相同。
        2
    MaxStack   19 天前
    对的,你指的应该是 modCount 吧,如果有修改的话抛异常 ConcurrentModificationException。这部分是有用的。

    我是觉得遍历数组依次输出这部分没必要。
    ~~~
    if (modCount != expectedModCount) {
    throw new ConcurrentModificationException();
    }
    ~~~
        3
    SoloCompany   19 天前
    1. elementData 又不总是满的
    2. 应尽量确保值相等的 array list 总是得到同样的序列化结果
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1767 人在线   最高记录 5043   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 16ms · UTC 01:06 · PVG 09:06 · LAX 18:06 · JFK 21:06
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1