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

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

  •  1
     
  •   MaxStack · 2019-05-27 15:35:17 +08:00 · 1750 次点击
    这是一个创建于 2016 天前的主题,其中的信息可能已经有所发展或是发生改变。

    看了下 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 测试,是可以直接序列化+反序列化数组的。

    求大神指点。

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

    我是觉得遍历数组依次输出这部分没必要。
    ~~~
    if (modCount != expectedModCount) {
    throw new ConcurrentModificationException();
    }
    ~~~
    SoloCompany
        3
    SoloCompany  
       2019-05-27 20:32:40 +08:00
    1. elementData 又不总是满的
    2. 应尽量确保值相等的 array list 总是得到同样的序列化结果
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1011 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 20:34 · PVG 04:34 · LAX 12:34 · JFK 15:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.