ArrayList集合中的elementData为什么不参与序列化?

摘要:
ArrayList中有这样一个代码/***,用于存储ArrayList元素的数组缓冲区。ArrayList的容量是此数组缓冲区的长度*/transientObject[]elementData;//非私有的to实现estedclassaccesselementData是一个数组,它存储当前集合中的所有元素,但用transient关键字修饰。瞬态意味着数组不参与序列化。在这种情况下,ArrayList中存储的元素将在序列化后丢失?有了这样一个问题,我往下看,发现ArrayList中有两个方法:writeObject()和readObject()/***,用于将ArrayList实例的状态保存到流中。

在ArrayList中有这么一段代码 

  /**
     * 存储ArrayList元素的数组缓冲区。ArrayList的容量是此数组缓冲区的长度。
* 添加第一个元素时,任何带有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList都将扩展为DEFAULT_CAPACITY。
*/ transient Object[] elementData; // non-private to simplify nested class access

elementData是存放当前集合中所有的元素的一个数组,但是却被transient关键字修饰,transient表示该数组不参与序列化.

那这样的话,序列化之后ArrayList中存放的元素不就丢失了吗?

带着这样的疑问接着往下看,最后发现在ArrayList中有这样两个方法 writeObject() 和 readObject()

  /**
     * 将 ArrayList 实例的状态保存到流(即序列化它)。*/
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
        // 写出元素计数和任何隐藏的东西
        int expectedModCount = modCount;
        s.defaultWriteObject(); // 写出当前类的所有非静态字段(non-static)和非瞬态字段(non-transient)到ObjectOutputStream

        // 将size写出到ObjectOutputStream
        s.writeInt(size);

        // 因为ArrayList是可扩容的,在添加元素时,可能会扩容,这个时候会存在一些没有使用的空间,所以采用这种方式,来节约空间和减少序列化的时间
        for (int i=0; i<size; i++) {  // size代表数组中储存的元素的个数
            s.writeObject(elementData[i]); // 有序的将elementData中已使用的元素读出到流中
        }

        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }
  /**
     * 从流中重构 ArrayList 实例(即,对其进行反序列化)。
     */
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        elementData = EMPTY_ELEMENTDATA;

        // 读入size, 和所有隐藏的东西
        s.defaultReadObject();

        // 读入容量
        s.readInt(); // ignored

        if (size > 0) {
            // 就像clone()一样,根据大小而不是容量来分配数组
            ensureCapacityInternal(size);

            Object[] a = elementData;
            // 按正确的顺序读入所有元素。
            for (int i=0; i<size; i++) {
                a[i] = s.readObject();
            }
        }
    }

免责声明:文章转载自《ArrayList集合中的elementData为什么不参与序列化?》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java事务Android 中Webview 自适应屏幕下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C# 序列化与反序列化Serialization之Json Xml Binary Soap JavaScript序列化

所谓的序列化其实就是把一个内存中的对象信息转化成一个可以持久化保存的形式,方便保存数据库和文件或着用于传输, 序列化的主要作用是不同平台之间进行通信与信息的传递保存等,常用的有序列化有Json Xml Binary Soap JavaScript序列化等,当然我们也可以使用第三方的序列化类库,第三方的序列化类库可以参照网上的,这里不再赘述, 本文主要介绍J...

spark作业性能调优

spark作业性能调优 优化的目标 保证大数据量下任务运行成功 降低资源消耗 提高计算性能 一、开发调优: (1)避免创建重复的RDD RDD lineage,也就是“RDD的血缘关系链” 开发RDD lineage极其冗长的Spark作业时,创建多个代表相同数据的RDD,进而增加了作业的性能开销。 (2)尽可能复用同一个RDD 比如说,有一个RDD的...

RPC简介及原理介绍

RPC简介及原理介绍 背景 在前面的课程《Go语言微服务理论与实践课程》课程中,我们已经学习了微服务的理论知识,了解了微服务实践中需要解决哪些问题。 从本篇技术文档开始,我们进入新的微服务内容的学习。在本系列课程中,我们会着重讲框架的内容,主要包括两个:gRPC框架、go-micro框架。 首先来学习gRPC框架相关的内容。 本地过程调用 让我们先来看看正...

序列化器关系 (Serializer relations)

糟糕的程序员担心代码。好的程序员担心数据结构和它们的关系。—— Linus Torvalds 关系字段用于表示模型关系。它们可以应用于 ForeignKey,ManyToManyField 和 OneToOneField 关系,以及反向关系和自定义关系 (例如:GenericForeignKey)。 注意:关系字段在 relations.py 中声明,但...

Java ArrayList【笔记】

Java ArrayList【笔记】 ArrayList ArrayList基本结构 ArrayList 整体架构比较简单,就是一个数组结构 源码中的基本概念 index 表示数组的下标,从 0 开始计数 elementData 表示数组本身 DEFAULT_CAPACITY 表示数组的初始大小,默认是 10 size 表示当前数组的大小,类型 int,...

C#在窗体间的数据交互的经验总结

导读:本文详细讨论了在C#中两个窗体间通讯的方法,分为如下几类1。利用构造函数进行窗体单向通信2。利用引用变量进行窗体单向通信3。演示利用引用ArrayList变量进行窗体双向通信4。使用form类的owner属性在两个窗体间通讯5。利用自定义属性在两个窗体间通6。利用静态类在两个窗口间通讯猪悟能编写了本文演示代码,在本文最后有下载链接。 Windows...