Почему поле размера ArrayList не является временным?
Java использует пользовательскую сериализацию и явно записывает
size
. Тем не менее, размер не указан в
ArrayList
в качестве
transient
. Почему размер пишется два раза: один раз через
defaultWriteObject
и снова вис
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]);
}
1 ответ
TL;DR
Он существует исключительно для совместимости со старыми версиями java.
Детали
Если вы посмотрите на комментарий выше
s.writeInt(size)
, вы можете видеть, что это должна быть емкость. В предыдущих версиях Java сериализованная форма имела размер и емкость.
Оба они представляют фактические свойства файла . В
size
представляет количество элементов в то время как
capacity
относится к количеству возможных элементов (длина массива) в нем без необходимости повторного создания массива.
Если вы посмотрите на
readObject
, вы можете видеть, что емкость игнорируется:
// Read in capacity
s.readInt(); // ignored
Это связано с тем, что он использовался в предыдущих версиях Java, и его все еще необходимо писать/читать для сохранения совместимости.
Если вы посмотрите на соответствующие исходные коды JDK6 , вы увидите, что это действительно использовалось ранее. Если у вас есть сериализованный JDK6 и вы пытаетесь десериализовать его с помощью более нового JDK, это сработает. Но если бы емкость была просто пропущена, это потерпело бы неудачу, и вы не могли бы ничего десериализовать с помощью
ArrayList
из этой старой версии.