Сериализация в Java
От: Idsa Россия  
Дата: 11.10.09 18:07
Оценка:
Коллеги, просветите .NET'чика Гугл не помог, поэтому обращаюсь к вам.

В .NET есть несколько стандартных механизмов сериализации: на базе полей (BinaryFormatter, SoapFormatter), на базе свойств (XmlSerializer) и смешанные (DataContractSerializer). В Java же я сталкивался только с сериализацией на базе полей с наследованием от интерфейса ISerializable. Хоть в Java и нет свойств, хотел уточнить, нет ли других механизмов сериализации в Java (по сути, академический интерес).

Это не все

Правильно ли я понял, что marker interfaces (например, все тот же ISerializable) имели смысл лишь до появления в Java 5 annotations? Сейчас их не используют?

Если проводить аналогию с .NET, механизм Java-сериализации больше всего похож на .NET Formatter'ы (BinaryFormatter, SoapFormatter). Правда, есть одно фундаментальное отличие. В Java, реализуя ISerializable, мы делаем сериализуемыми всех его потомков (только если они не "скажут" обратного). В .NET для того чтобы пометить класс сериализуемым, необходимо применить к нему атрибут (аналог аннотаций в Java) Serializable, причем этот атрибут не Inherited (то есть наследники этого класса не станут автоматически сериализуемыми). Я считаю сериализацию очень важным и сложным процессом и убежден, что программист должен осознанно указать, что класс сериализуем (и при этом реализовать дополнительные интерфейсы в случае необходимости кастомизации). В .NET именно так и происходит, в Java все пущено на самотек (не сочтите за холивар). Хотелось услышать мнения профессионалов Java по этому поводу.
Re: Сериализация в Java
От: mazurkin http://mazurkin.info
Дата: 11.10.09 18:39
Оценка: 5 (3) +1
Idsa wrote:

> В .NET есть несколько стандартных механизмов сериализации: на базе

> полей (BinaryFormatter, SoapFormatter), на базе свойств
> (XmlSerializer) и смешанные (DataContractSerializer). В Java же я
> сталкивался только с сериализацией на базе полей с наследованием от
> интерфейса ISerializable. Хоть в Java и нет свойств, хотел уточнить,
> нет ли других механизмов сериализации в Java (по сути, академический
> интерес).

Serializable (без венгерской нотации с "I"), а также Externalizable —
очень древние маркерные интерфейс предназначенные для сохранения
объектов в бинарном виде.

> Правильно ли я понял, что marker interfaces (например, все тот же

> ISerializable) имели смысл лишь до появления в Java 5 annotations?
> Сейчас их не используют?

С аннотациями эти интерфейсы никак не связаны и они никак друг на друга
не влияют.

> Если проводить аналогию с .NET, механизм Java-сериализации больше

> всего похож на .NET Formatter'ы (BinaryFormatter, SoapFormatter).

Вообще Serializable/Externalizable — являются фундаметальными фичами JVM
для сериализации классов в бинарный формат. В современном гетерогенном
мире сериализация в бинарный формат (неудобный и java-ориентированный)
встречается все реже и реже.

В основном сейчас сериализуют в XML — а вот тут решений очень много. Из
штатных можно упомянуть JAXB, сторонние библиотеки — Castor, XStream и
куча других — сейчас нам подскажут.

Если вам все таки нужно сериализовать в бинарный формат и сделать это по
своему — то можно все сделать на базе интерфейса Externalizable — он
позволяет все контролировать.

Если вам нужно сериализовать и не в бинарный вид, и не в XML — то тут
помогут решения на базе reflection, для убыстрения можно использовать
библиотеки использующие code generation.

> Правда, есть одно фундаментальное отличие. В Java, реализуя

> ISerializable, мы делаем сериализуемыми всех его потомков (только
> если они не "скажут" обратного). В .NET для того чтобы пометить класс
> сериализуемым, необходимо применить к нему атрибут (аналог аннотаций
> в Java) Serializable, причем этот атрибут не Inherited (то есть
> наследники этого класса не станут автоматически сериализуемыми). Я
> считаю сериализацию очень важным и сложным процессом и убежден, что
> программист должен осознанно указать, что класс сериализуем (и при
> этом реализовать дополнительные интерфейсы в случае необходимости
> кастомизации). В .NET именно так и происходит, в Java все пущено на
> самотек (не сочтите за холивар). Хотелось услышать мнения
> профессионалов Java по этому поводу.

Конкретно насчет этого — лично я не согласен с вами совершенно.

В джаве очень мало что пущено на самотек — все очень продумано на самом
деле

Вы пометили базовый класс как сериализуемый. После того как вы
реализовали сабкласс от этого базового класса, он автоматически
становится сериализуемым. И это очень правильно. Почитайте про принцип
подстановки Лискоу — рассматриваемая тема крайне близка к тому о чем
говорит этот принцип. В кратце: если у вас есть алгоритм, который
работает с суперклассом и расчитывает на его сериализуемость, то этот
алгоритм обязан работать правильно также и со всеми сабклассами этого
суперкласса — то есть они также дожны быть сериализуемы.
Posted via RSDN NNTP Server 2.1 beta
Re: Сериализация в Java
От: von Zeppelin Россия  
Дата: 11.10.09 18:55
Оценка:
Здравствуйте, Idsa, Вы писали:

I>Коллеги, просветите .NET'чика Гугл не помог, поэтому обращаюсь к вам.


Насколько помню, сериализация по умолчанию в .NET обеспечивается атрибутом [Serializable]. BinaryFormatter и SoapFormatter — форматтеры, которые при сериализации определяют формат сохранения данных в поток: в бинарной форме (компактно, быстро, но не интероперабельно) или XML (возможность взаимодействия с другими системами, понятно для чтения человеком). Поля, которые не предназначены для сериализации, помечаются атрибутом [NonSerialized].
XmlSerializer скорее имеет отношение к XML Binding, в Java для этого есть JAXB. Про DataContractSerializer сказать не могу, не сталкивался, видимо, для обеспечения custom формата.

В Java класс помечается как пригодный для сериализации с помощью маркерного интерфейса java.io.Serializable. Поля, которые не предназначены для сериализации, помечаются модификатором transient.
Если нужна своя логика для управления процессом сериализации — есть интерфейс Externalizable.
Тонкости более подробно есть здесь, например, про методы readObject() / writeObject().

Интерфейс Serializable используется и в версиях Java >= 5.0, атрибуты нового здесь не внесли.
Re: Сериализация в Java
От: dotidot Россия  
Дата: 11.10.09 19:56
Оценка:
Здравствуйте, Idsa, Вы писали:
I>Хотелось услышать мнения профессионалов Java по этому поводу.
это древняя сильно завязанная на саму яву вещь. лучше её избегать по возможности, там много подводных камней(читайте книжки). для персистенса удобнее пользоваться orm-мами, для ipc — биндингами к xml и вебсервисами.
Re: Сериализация в Java
От: GarryIV  
Дата: 11.10.09 20:48
Оценка: 3 (1)
Здравствуйте, Idsa, Вы писали:

I>Коллеги, просветите .NET'чика Гугл не помог, поэтому обращаюсь к вам.


I>В .NET есть несколько стандартных механизмов сериализации: на базе полей (BinaryFormatter, SoapFormatter), на базе свойств (XmlSerializer) и смешанные (DataContractSerializer). В Java же я сталкивался только с сериализацией на базе полей с наследованием от интерфейса ISerializable. Хоть в Java и нет свойств, хотел уточнить, нет ли других механизмов сериализации в Java (по сути, академический интерес).


Есть куча всего. Например JAXB — вполне себе на базе свойств.
Кстати свойства де-факто в Java есть только не на уровне языка а на уровне библиотек.

I>Это не все


I>Правильно ли я понял, что marker interfaces (например, все тот же ISerializable) имели смысл лишь до появления в Java 5 annotations? Сейчас их не используют?


По большому счету да. Но местами таки marker interface удобнее.

I>Если проводить аналогию с .NET, механизм Java-сериализации больше всего похож на .NET Formatter'ы (BinaryFormatter, SoapFormatter). Правда, есть одно фундаментальное отличие. В Java, реализуя ISerializable, мы делаем сериализуемыми всех его потомков (только если они не "скажут" обратного). В .NET для того чтобы пометить класс сериализуемым, необходимо применить к нему атрибут (аналог аннотаций в Java) Serializable, причем этот атрибут не Inherited (то есть наследники этого класса не станут автоматически сериализуемыми). Я считаю сериализацию очень важным и сложным процессом и убежден, что программист должен осознанно указать, что класс сериализуем (и при этом реализовать дополнительные интерфейсы в случае необходимости кастомизации). В .NET именно так и происходит, в Java все пущено на самотек (не сочтите за холивар). Хотелось услышать мнения профессионалов Java по этому поводу.


Есть такое дело...
WBR, Igor Evgrafov
Re[2]: Сериализация в Java
От: Blazkowicz Россия  
Дата: 12.10.09 08:20
Оценка:
Здравствуйте, mazurkin, Вы писали:

M>В основном сейчас сериализуют в XML — а вот тут решений очень много. Из

M>штатных можно упомянуть JAXB, сторонние библиотеки — Castor, XStream и
M>куча других — сейчас нам подскажут.
Уже здесь. Подсказываю: JiBX, XMLBeanEncoder. Опять же XML сериализаторы бывают с маппингом и без.

M>Если вам все таки нужно сериализовать в бинарный формат и сделать это по

M>своему — то можно все сделать на базе интерфейса Externalizable — он
M>позволяет все контролировать.
А ещё есть Hessian.

M>Если вам нужно сериализовать и не в бинарный вид, и не в XML — то тут

M>помогут решения на базе reflection, для убыстрения можно использовать
M>библиотеки использующие code generation.
Кодогенерация, конечно же быстрее. Но самописная кодогенерация это серьезное зло, которое трудно отлаживать и исправлять. Поэтому применяется в крайне редких случаях.
http://rsdn.org/File/13923/ukliam3.gif
Re[2]: Сериализация в Java
От: Idsa Россия  
Дата: 17.10.09 18:00
Оценка:
Здравствуйте, mazurkin, Вы писали:

M>С аннотациями эти интерфейсы никак не связаны и они никак друг на друга

M>не влияют.

Разве? Понятно, что для обратной совместимости в старом коде останутся маркерные интерфейсы... но в новом коде, как мне кажется, аннотации должны их заменить.

M>Вообще Serializable/Externalizable — являются фундаметальными фичами JVM

M>для сериализации классов в бинарный формат. В современном гетерогенном
M>мире сериализация в бинарный формат (неудобный и java-ориентированный)
M>встречается все реже и реже.

Но ведь никто не мешает на базе этих фич реализовать XML-сериализацию. Более того, наверняка, такие реализации есть.

M>В основном сейчас сериализуют в XML — а вот тут решений очень много. Из

M>штатных можно упомянуть JAXB, сторонние библиотеки — Castor, XStream и
M>куча других — сейчас нам подскажут.

Спасибо за примеры.

M>Конкретно насчет этого — лично я не согласен с вами совершенно.


Давайте обсудим

M>В джаве очень мало что пущено на самотек — все очень продумано на самом

M>деле

Прям все? Так не бывает

M>Вы пометили базовый класс как сериализуемый. После того как вы

M>реализовали сабкласс от этого базового класса, он автоматически
M>становится сериализуемым. И это очень правильно. Почитайте про принцип
M>подстановки Лискоу — рассматриваемая тема крайне близка к тому о чем
M>говорит этот принцип.

Считаю, что принцип подстановки Лискоу здесь ни при чем. Ведь по сути, маркерные интерфейсы — это всего лишь уродливая форма задания метаданных. А ведь далеко не все метаданные наследуются от предка к родителю (те же атрибуты в .NET могут как неследоваться, так и не наследоваться). Поэтому сериализуемость потомков мне видится следствием использования интерфейсов в качестве способа задания метаданных (в отсутствие на тот момент альтернатив).

Представьте, к чему может привести такая "забота" о дочерних классах. Ведь некоторый сложный класс, который и не должен подлежать сериализации (по крайней мере без кастомизации) может оказаться сериализуемым благодаря предку. Почему разработчик не пометил класс как несериализуемый? Например, 1. просто забыл 2. или на момент написания класса базовый класс не был Serializable, а потом по определенным соображениям им стал и т. д. Именно поэтому я считаю, что сериализуемость каждого определенного класса должна сознательно определяться разработчиком, а не наследоваться свыше.
Re[2]: Сериализация в Java
От: Idsa Россия  
Дата: 17.10.09 18:05
Оценка:
Здравствуйте, von Zeppelin, Вы писали:

VZ>Интерфейс Serializable используется и в версиях Java >= 5.0, атрибуты нового здесь не внесли.


Против обратной совместимости не попрешь — я спрашивал про судьбу маркерных интерфейсов в новом коде.
Re[2]: Сериализация в Java
От: Idsa Россия  
Дата: 17.10.09 18:09
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>По большому счету да. Но местами таки marker interface удобнее.


А где, например? Ведь в Java можно пометить аннотацию наследуемой для дочерних классов?

GIV>Есть такое дело...


А в ветке выше есть другое мнение. Присоединяйтесь — интересно, к чему прийдем
Re[3]: Сериализация в Java
От: von Zeppelin Россия  
Дата: 17.10.09 19:18
Оценка: -1
Здравствуйте, Idsa, Вы писали:

I>Против обратной совместимости не попрешь — я спрашивал про судьбу маркерных интерфейсов в новом коде.

Они как использовались так и используются, по крайней мере, что касается сериализации. Аннотации @Serializable или ей подобной в Java нет.

I>Ведь в Java можно пометить аннотацию наследуемой для дочерних классов?

Нет, аннотации не наследуются.

I>Считаю, что принцип подстановки Лискоу здесь ни при чем

Как раз при чем. Пусть есть абстрактный класс Component, представляющий GUI-компонент. Предполагается возможность сохранения состояния форм приложения между запусками, например, путем записи в файл совокупности компонентов формы при завершении приложения и чтения при запуске. Естественным здесь кажется сделать класс Component сериализуемым и требовать такого поведения ото всех потомков. При необходимости в потомке можно реализовать свою логику сериализации или, в крайнем случае, сделать ее по каким-либо причинам невозможной (генерацией NotSerializableException).
Re[3]: Сериализация в Java
От: mazurkin http://mazurkin.info
Дата: 17.10.09 19:20
Оценка:
Idsa wrote:

> Разве? Понятно, что для обратной совместимости в старом коде

> останутся маркерные интерфейсы... но в новом коде, как мне кажется,
> аннотации должны их заменить.

Про какие аннотации, которые должны заменить интерфейс Serializable вы
говорите — я не понимаю?

> Но ведь никто не мешает на базе этих фич реализовать

> XML-сериализацию. Более того, наверняка, такие реализации есть.

Все существующие XML сериализации работают либо на базе своих
собственных меток-аннотаций, либо на базе конфигурационных файлов, либо
автоматически — на базе доступных пропертей JavaBean. И все они
игнорируют Serializable/Externalizable чуть более, чем полностью.

> Считаю, что принцип подстановки Лискоу здесь ни при чем. Ведь по

> сути, маркерные интерфейсы — это всего лишь уродливая форма задания
> метаданных. А ведь далеко не все метаданные наследуются от предка к
> родителю (те же атрибуты в .NET могут как неследоваться, так и не
> наследоваться). Поэтому сериализуемость потомков мне видится
> следствием использования интерфейсов в качестве способа задания
> метаданных (в отсутствие на тот момент альтернатив).

> Представьте, к чему может привести такая "забота" о дочерних классах.

> Ведь некоторый сложный класс, который и не должен подлежать
> сериализации (по крайней мере без кастомизации) может оказаться
> сериализуемым благодаря предку. Почему разработчик не пометил класс
> как несериализуемый? Например, 1. просто забыл 2. или на момент
> написания класса базовый класс не был Serializable, а потом по
> определенным соображениям им стал и т. д. Именно поэтому я считаю,
> что сериализуемость каждого определенного класса должна сознательно
> определяться разработчиком, а не наследоваться свыше.

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

С другой стороны я плохо понял ваши доводы — если вам очень сильно надо
предохранить дочерние классы от сериализации (не могу понять зачем) —
переопределите readObject и writeObject и возбуждыйте в них
UnsopportedOperationException или что вам больше нравится.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: Сериализация в Java
От: avpavlov  
Дата: 18.10.09 06:54
Оценка:
I>>Ведь в Java можно пометить аннотацию наследуемой для дочерних классов?
VZ>Нет, аннотации не наследуются.

Наследуются. Почитай чем отличаются методы getAnnotations() и getDeclaredAnnotations() (хотя и из имени уже всё ясно)
Re[3]: Сериализация в Java
От: Baudolino Германия  
Дата: 18.10.09 07:16
Оценка:
B>Кодогенерация, конечно же быстрее. Но самописная кодогенерация это серьезное зло, которое трудно отлаживать и исправлять. Поэтому применяется в крайне редких случаях.
e4 построен на EMF чуть более, чем полностью, а EMF это в том числе и кодогенератор. Сериализация в EMF, кстати, хорошо кастомизируется.
Re[5]: Сериализация в Java
От: Idsa Россия  
Дата: 18.10.09 13:14
Оценка:
Здравствуйте, avpavlov, Вы писали:

A>Наследуются. Почитай чем отличаются методы getAnnotations() и getDeclaredAnnotations() (хотя и из имени уже всё ясно)


Ну тогда моей фантазии не хватает для того, чтобы придумать варианты использования для маркерных аннотаций вместо интерфейсов.
Re[4]: Сериализация в Java
От: Idsa Россия  
Дата: 18.10.09 13:28
Оценка:
Здравствуйте, mazurkin, Вы писали:

M>Про какие аннотации, которые должны заменить интерфейс Serializable вы

M>говорите — я не понимаю?

Я как человек, плотно не работающий с Java, спрашиваю, есть ли место использованию маркерных интерфейсов в современной Java (>= 5).

M>Я уже написал почему считаю, что все дочерние классы должны (обязаны)

M>быть сериализуемы, в случае когда сериализуем супер-класс. И принцип
M>Лискоу здесь также очень в тему.

Принцип подстановки Лискоу подразумевает приведение наследника к типу предка. Serializable же, будучи маркерным интерфейсом, не подразумевает реализации какой-либо логики. Именно поэтому мне кажется, что принцип подстановки Лискоу здесь притянут за уши. К этому меня подталкивает и практический опыт: реализация в .NET (напомню, что в .NET атрибут ISeralizable намеренно сделан ненаследуемым) гораздо надежнее. Если уж в .NET класс помечен Serializable, то это сделано сознательно, и вероятность получить сюрприз с сериализацией существенно ниже.

M>С другой стороны я плохо понял ваши доводы — если вам очень сильно надо

M>предохранить дочерние классы от сериализации (не могу понять зачем) -
M>переопределите readObject и writeObject и возбуждыйте в них
M>UnsopportedOperationException или что вам больше нравится.

Выше я рассуждал как пользователь некоторого абстрактного фреймворка, в котором сериализуемые (благодяря сериализуемому предку) классы на деле сериализуются абы как.
Re[5]: Сериализация в Java
От: mazurkin http://mazurkin.info
Дата: 18.10.09 15:03
Оценка:
Idsa wrote:

> Я как человек, плотно не работающий с Java, спрашиваю, есть ли место

> использованию маркерных интерфейсов в современной Java (>= 5).

Как вам уже тут сказали, ничего не изменилось кроме того, что
актуальность бинарной сериализации постепенно уменьшается.

> Принцип подстановки Лискоу подразумевает приведение наследника к типу

> предка.

Вы очень узко трактуете.

Я уверен в том, что принцип подстановки Лискоу говорит о том, что если у
нас есть некий абстрактный алгоритм корректно работающий с неким
классом, то мы ОБЯЗАНЫ создавать субклассы от этого класса таким
образом, чтобы работа алгоритма не нарушалась. Приведение же типов к
базовому классу — лишь фундаментальный принцип, который не требует
привлечения нашего внимания в данном случае.

И опять же, в нашем случае очевидно, что если алгоритм рассчитывает на
сериализацию некого класса, то, если дочерние классы не сериализуемы,
алгоритм работать нормально не будет.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: Сериализация в Java
От: Sergey Astakhov Россия  
Дата: 18.10.09 17:26
Оценка:
Здравствуйте, von Zeppelin, Вы писали:

I>>Ведь в Java можно пометить аннотацию наследуемой для дочерних классов?

VZ>Нет, аннотации не наследуются.

См. java.lang.annotation.Inherited
Re[5]: Сериализация в Java
От: Аноним  
Дата: 30.10.09 07:55
Оценка:
Здравствуйте, Idsa, Вы писали:


I>Принцип подстановки Лискоу подразумевает приведение наследника к типу предка. Serializable же, будучи маркерным интерфейсом, не подразумевает реализации какой-либо логики. Именно поэтому мне кажется, что принцип подстановки Лискоу здесь притянут за уши. К этому меня подталкивает и практический опыт: реализация в .NET (напомню, что в .NET атрибут ISeralizable намеренно сделан ненаследуемым) гораздо надежнее. Если уж в .NET класс помечен Serializable, то это сделано сознательно, и вероятность получить сюрприз с сериализацией существенно ниже.



Просветите, кто такой Лискоу?
Re[6]: Сериализация в Java
От: GarryIV  
Дата: 30.10.09 08:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Просветите, кто такой Лискоу?


Такая
Ну и собственно за что ее все знают
WBR, Igor Evgrafov
Re[3]: Сериализация в Java
От: GarryIV  
Дата: 30.10.09 19:12
Оценка: 1 (1)
Здравствуйте, Idsa, Вы писали:

I>Здравствуйте, GarryIV, Вы писали:

GIV>>По большому счету да. Но местами таки marker interface удобнее.

* можно делать методы someMethod(MarkerInterface o) — с аннотациями такое не прокатит.
* instanceof удобнее писать

I>А где, например? Ведь в Java можно пометить аннотацию наследуемой для дочерних классов?


GIV>>Есть такое дело...

I>А в ветке выше есть другое мнение. Присоединяйтесь — интересно, к чему прийдем

Я за тебя
WBR, Igor Evgrafov
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.