LinkedList序列化机制及反序列化后首尾节点定位问题咨询
LinkedList的序列化与反序列化机制详解
嘿,这个问题问到点子上了!确实,LinkedList的first和last字段都是transient修饰的,默认序列化不会保存这两个指针,那反序列化后怎么重新确定首尾元素的位置呢?核心在于LinkedList自定义了序列化和反序列化的逻辑,咱们一步步拆解:
一、序列化:只存元素,不存指针
LinkedList重写了private void writeObject(ObjectOutputStream s)方法,跳过默认的字段序列化,而是做了以下操作:
- 先写入序列化的元数据(比如序列化版本号)。
- 然后遍历整个链表,把每个节点的
item(也就是实际存储的元素)逐个写入输出流。 - 为什么不存
first、last和节点的prev/next指针?因为这些指针是JVM运行时的内存地址,序列化后毫无意义——反序列化时内存环境已经变了,旧的地址指向不了新创建的对象。而且只存元素能大幅减少序列化后的体积。
二、反序列化:重新构建链表,自动维护首尾指针
对应的,LinkedList也重写了private void readObject(ObjectInputStream s)方法,通过以下步骤恢复链表结构:
- 读取序列化时写入的元数据和元素总数。
- 逐个读取流中的元素,调用LinkedList的
add(E e)方法把元素依次添加到链表中。 - 关键就在
add方法的逻辑:- 当添加第一个元素时,会创建一个新的
Node节点,同时把first和last都指向这个节点,自然满足你提到的不变式:first.prev == null && first.item != null、last.next == null && last.item != null。 - 后续添加元素时,会把新节点挂在当前
last节点的next位置,更新新节点的prev指向原last,然后把last指针移到新节点上,始终保证last.next == null。
- 当添加第一个元素时,会创建一个新的
三、为什么要这么设计?
这种自定义序列化的方式,既避免了序列化无用的指针数据,又能在反序列化时通过常规的添加元素逻辑,自动维护好first和last指针的正确性,完美遵守了LinkedList的字段不变式规则。
内容的提问来源于stack exchange,提问作者Иван Гладуш
相关产品推荐
相关产品推荐

