Java的ArrayList使用自定义序列化并显式编写size.然而,尺寸在ArrayList中并没有标记为transient.为什么大小写两次:一次是通过defaultWriteObject,另一次是vis writeInt(size),如下所示(writeObject方法)?

s.defaultWriteObject();

// Write out size as capacity for behavioral 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]);
}

推荐答案

TL;博士

它的存在只是为了与旧的java版本兼容.

细节

如果你看一下s.writeInt(size)以上的 comments ,你会发现这应该是容量.在以前的java版本中,ArrayList的序列化形式具有大小和容量.

它们都代表了ArrayList的实际属性.size表示ArrayList中的项目数,而capacity表示其中不需要重新创建数组的可能项目数(数组长度).

如果你看一下readObject,你会发现容量被忽略了:

// Read in capacity
s.readInt(); // ignored

这是因为它在以前的java版本中使用过,仍然需要写入/读取以保持兼容性.

如果你看the matching JDK6 sources,你会发现这实际上是以前用过的.如果您有一个序列化的JDK6 ArrayList,并try 用一个较新的JDK对其进行反序列化,那么它会起作用.但是如果只是跳过了容量,这将失败,并且您无法使用旧版本的ArrayList反序列化任何内容.

Java相关问答推荐

Spring Boot@Cachebale批注未按预期工作

我无法获取我的Java Spring应用程序的Logback跟踪日志(log)输出

使用REST客户端和对象映射器从字符串反序列化Json

Java:使用Class.cast()将对象转换为原始数组

有没有办法让扩展变得多态?

在Spring终结点中,是否可以同时以大写和小写形式指定枚举常量?

Spring Security不允许加载js

使用PDFBox从PDF中删除图像

MimeMessage emlMessage=new MimeMessage(Session,emlInputStream);抛出InvocationTargetException

Sack()步骤中的合并运算符未按预期工作

迁移到Java 17后,日期显示不准确

在macOS上读取文件会导致FileNotFound,即使文件存在(并且具有权限)

如何在Jooq中获取临时表列引用?

使用for循环时出现堆栈溢出错误,但如果使用if块执行相同的操作,则不会产生错误

视图被推出线性布局-Android

我们可以在方法中声明接口吗?

Java System.getProperty在哪里检索user.home?

读取ConcurrentHashMap中的可变对象

使用StringBuilder和append方法创建字符串时Java字符串内部方法的问题

这是JavaFX SceneBuilder的错误吗?