Совместима ли сериализация Java-объектов между 1,5 и 1,6? - PullRequest
20 голосов
/ 30 сентября 2008

Мне интересно, безопасно ли смешивать сериализацию объектов jdk 1.5 и 1.6 (Java 6) (двунаправленная связь). Я искал явное утверждение от Sun по этому вопросу, но безуспешно. Поэтому, помимо технической осуществимости, я ищу "официальное" заявление по проблеме.

Ответы [ 8 ]

16 голосов
/ 30 сентября 2008

Сам механизм сериализации не изменился. Для отдельных классов это будет зависеть от конкретного класса. Если класс имеет поле serialVersionUID, это должно указывать на совместимость сериализации.

Что-то вроде:

private static final long serialVersionUID = 8683452581122892189L;

Если оно не изменилось, сериализованные версии совместимы. Для классов JDK это гарантировано, но, конечно, всегда можно забыть обновить serialVersionUID после внесения критических изменений.

Когда классы JDK не гарантированно совместимы, это обычно упоминается в Javadoc.

Предупреждение. Сериализированные объекты этого класса не будут совместимы с будущими выпусками Swing

3 голосов
/ 30 сентября 2008

Механизм сериализации в 1.5 и 1.6 совместим. Таким образом, один и тот же код, скомпилированный / работающий в контексте 1.5 и 1.6, может обмениваться сериализованными объектами. Вопрос о том, имеют ли два экземпляра ВМ одинаковую / совместимую версию класса (как может указывать поле serialVersionUID), - это другой вопрос, не связанный с версией JDK.

Если у вас есть один сериализуемый Foo.java и вы используете его в JDK / VM 1.5 и 1.6, сериализованные экземпляры Foo создаются одним V; может быть десериализован другим.

2 голосов
/ 30 сентября 2008

Вы прочитали Спецификацию сериализации Java-объекта ? Есть тема по версиям . Также есть статья для разработчиков классов: Откройте для себя секреты Java Serialization API . Каждый выпуск Java сопровождается примечаниями по совместимости .

Из спецификации Java 6 по сериализации:


Цели:

  • Поддержка двунаправленной связи между различными версиями класса, работающими на разных виртуальных машинах, путем:
    • Определение механизма, который позволяет классам JavaTM читать потоки, написанные более старыми версиями того же класса.
    • Определение механизма, который позволяет классам JavaTM записывать потоки, предназначенные для чтения более старыми версиями того же класса.
  • Обеспечить сериализацию по умолчанию для персистентности и RMI.
  • Хорошо выполнять и создавать компактные потоки в простых случаях, чтобы RMI могла использовать сериализацию.
  • Уметь идентифицировать и загружать классы, которые точно соответствуют классу, используемому для записи потока.
  • Сохраняйте накладные расходы низкими для неверсированных классов.
  • Используйте формат потока, который позволяет обойти поток без необходимости вызывать методы, специфичные для объектов, сохраненных в потоке.

2 голосов
/ 30 сентября 2008

Если не указано иное, это должно быть частью двоичной совместимости. Классы Swing явно не совместимы между версиями. Если вы обнаружите проблему с другими классами, сообщите об ошибке на bugs.sun.com .

2 голосов
/ 30 сентября 2008

Я бы быстро добавил, что можно изменить класс, но забудьте , чтобы изменить serialVersionUID. Поэтому неверно, что «если класс определяет serialVersionUID, и это не меняется, класс гарантированно будет совместимым». Скорее, наличие того же serialVersionUID - это способ, которым API обещает обратную совместимость.

2 голосов
/ 30 сентября 2008

После тестирования с сериализованным объектом, записанным в файл с использованием ObjectOutputStream в программе на Java 1.5, а затем запустив чтение с ObjectInputStream в программе на Java 1.6, я могу сказать, что это работало без проблем.

0 голосов
/ 11 декабря 2008

Смешивать Java 1.5 и 1.6 небезопасно. Например, у меня есть объект Java 1.5, сериализованный в файл, и я попытался открыть его в Java 1.6, но при этом возникла ошибка, приведенная ниже.

java.io.InvalidClassException: javax.swing.JComponent; local class incompatible: stream classdesc serialVersionUID = 7917968344860800289, local class serialVersionUID = -1030230214076481435
    at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readArray(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readArray(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
0 голосов
/ 01 октября 2008

Обратите внимание, что спецификация Java Beans описывает независимый от версии метод сериализации, который обеспечивает сильную обратную совместимость. Это также приводит к читаемым «сериализованным» формам. На самом деле сериализованный объект может быть создан довольно легко с помощью механизма.

Просмотрите документацию к классам XMLEncoder и XMLDecoder.

Я бы не стал использовать это для передачи объекта по проводам (хотя, если требуется высокая производительность, я бы тоже не использовал сериализацию), но это неоценимо для постоянного хранения объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...