Разве сериализация не всегда заканчивается сериализацией примитивных типов?

Я использую Kryo для создания сохранений игр в коде, над которым работаю.

Используя сериализатор по умолчанию, FieldSerializer, я сериализую один массивный POJO. Это класс, который содержит другие созданные мной классы и примитивные типы.

Все состояние моего игрового мира сохраняется и загружается полностью правильно, без создания каких-либо пользовательских сериализаторов.

  • Разве не все деревья классов изначально построены из примитивных типов данных?
  • Зачем вам нужен какой-то другой сериализатор?

Единственное, о чем я могу думать, это об улучшении дискового пространства или скорости сериализации/десериализации.


person crossingTime    schedule 18.02.2016    source источник


Ответы (1)


Да, в идеальном мире вы должны только сериализовать pojos, а pojos должно быть «деревом примитивных типов данных». Но это не так просто.

Чтобы быть быстрым, Kryo по умолчанию не использует сериализацию Java. У него есть собственный сериализатор FieldSerializer, который анализирует экземпляры и сериализует поля за полями. Этот сериализатор не использует метод по умолчанию, такой как readResolve writeReplace, и не может восстановить поведение некоторых объектов.

Например, представьте себе простой POJO, которому принадлежит свойство Date. Эти «примитивные типы данных» не имеют сериализуемых полей (все они помечены как переходные): его процесс сериализации выполняется через readObject или writeObject: FieldSerializer по умолчанию не будет работать.

Если у вашего POJO есть свойство коллекции, и вы создаете экземпляр с помощью Collections.emptyList(), то это может работать... или нет: коллекция "emptyList" должна быть одноэлементной, и это поведение выполняется с помощью метода readResolve. FieldSerializer не знает об этом.

Kryo поставляется с набором сериализаторов по умолчанию, которые могут обрабатывать такие типы, но иногда вам нужно создать свой собственный для обработки класса с определенным поведением. Но обычно вы создаете сериализатор для повышения скорости классов, которые вы часто сериализуете, а не потому, что Kryo не может их сериализовать.

Kryo поставляется со специальным сериализатором, JavaSerializer или ExternalizableSerializer, которые используют сериализацию Java по умолчанию, но они не позволяют Kryo "видеть" внутренние поля, и вы теряете все преимущества использования Kryo.

person Jérémie B    schedule 18.02.2016
comment
Я не уверен, что полностью понимаю пример с датой, который вы привели. docs.oracle.com/javase/7/docs/ api/java/util/Date.html реализует Serializable, но не содержит полей. Не могли бы вы объяснить тот же пример по-другому? - person crossingTime; 19.02.2016
comment
Посмотрите исходники класса Date: все поля помечены как переходные, сериализация делается через readObject и writeObject. Вы не можете просто скопировать поле, как в Kryo FieldSerializer. hg. openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/ - person Jérémie B; 19.02.2016