发布于2026-05-23 阅读(0)
扫一扫,手机访问

说到集合类的序列化,一个经典的优化案例就藏在 ArrayList 里。默认情况下,序列化机制会老老实实地把整个内部数组 elementData 都写出去,包括那些还没用上的空闲槽位——也就是 size 之后的那些 null。这显然不划算,既浪费传输带宽,反序列化后还会白占着内存。那怎么办呢?ArrayList 的答案是:自己动手,丰衣足食。它通过自定义 writeObject 方法,只挑实际有效的元素进行序列化。
一切优化的前提,是底层数组 elementData 被声明为 transient。这个关键字的作用很关键:
null)被一股脑儿地写入流中。transient 声明,为后续的精简写入扫清了障碍,铺平了道路。这个自定义的 writeObject 方法,会在 ObjectOutputStream 进行序列化时通过反射被调用。它的执行步骤非常清晰:
defaultWriteObject(),把那些非 transient 的成员变量(比如至关重要的 size)先序列化好。elementData[0] 到 elementData[size - 1] 这个范围,将每一个实际存在的元素逐个写入流。size 之后的内存位置,无论里面是什么,都一概不理。这就从源头上杜绝了冗余数据的输出。有写就有读,配套的 readObject 方法负责在反序列化时精准重建对象。它的流程与写入过程遥相呼应:
defaultReadObject() 恢复出 size 等信息。size,直接分配一个恰到好处的新数组:elementData = new Object[size]。size 个元素,并依次填入新数组的对应下标。elementData 数组长度正好等于 size,一个空闲槽位都没有,内存利用堪称完美。这种设计带来的好处是实实在在的:
size 远小于数组容量时(比如只添加了5个元素,但容量已扩容到10),节省的效果尤为显著。null 引用,对内存友好的应用来说是个好消息。get()、add() 等操作行为与之前完全一致,功能上没有任何折损。最后需要明确的是,自定义序列化解决的仅仅是序列化/反序列化这个特定环节的效率问题。它并不会改变 ArrayList 原有的扩容逻辑,也与线程安全性无关。它就像是一个专注的后勤优化专家,只确保数据在“打包”和“拆包”过程中高效无损。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8