Почему Java нуждается в Serializable интерфейсе? - PullRequest
111 голосов
/ 14 января 2009

Мы интенсивно работаем с сериализацией, и необходимость указывать тег Serializable для каждого объекта, который мы используем, является своего рода бременем. Особенно когда это сторонний класс, который мы не можем изменить.

Вопрос: поскольку Serializable - пустой интерфейс, а Java обеспечивает надежную сериализацию после добавления implements Serializable - почему они не сделали все сериализуемым и все?

Чего мне не хватает?

Ответы [ 13 ]

114 голосов
/ 14 января 2009

Сериализация таит в себе подводные камни. Поддержка автоматической сериализации этой формы делает внутренние классы частью открытого API (именно поэтому javadoc предоставляет вам постоянные формы классов ).

Для долговременного сохранения класс должен иметь возможность декодировать эту форму, что ограничивает изменения, которые вы можете внести в дизайн класса. Это нарушает инкапсуляцию.

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

Существуют и другие проблемы, такие как нечетко определенная сериализованная форма внутренних классов.

Создание всех сериализуемых классов усугубит эти проблемы. Изучите Effective Java Second Edition , в частности Item 74: Осуществлять сериализацию разумно .

31 голосов
/ 14 января 2009

Я думаю, что на этот раз и Java, и люди .Net ошиблись, было бы лучше сделать все сериализуемым по умолчанию, и нужно отмечать только те классы, которые вместо этого нельзя безопасно сериализовать.

Например, в Smalltalk (язык, созданный в 70-х годах) каждый объект по умолчанию сериализуем. Я понятия не имею, почему это не так в Java, учитывая тот факт, что подавляющее большинство объектов безопасны для сериализации, а некоторые из них - нет.

Маркировка объекта как сериализуемого (с интерфейсом) волшебным образом не делает этот объект сериализуемым, он был сериализуем все время , просто теперь вы выразили то, что система могла найти самостоятельно. Поэтому я не вижу реальной причины для сериализации такой, какая она есть сейчас.

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

20 голосов
/ 14 января 2009

Не все по-настоящему сериализуемы. Возьмите, например, соединение с сетевым сокетом. Вы можете сериализовать данные / состояние вашего объекта сокета, но сущность активного соединения будет потеряна.

13 голосов
/ 14 января 2009

Основная роль Serializable в Java заключается в том, чтобы фактически сделать по умолчанию все другие объекты несериализуемыми. Сериализация - очень опасный механизм, особенно в реализации по умолчанию. Следовательно, как и дружба в C ++, она отключена по умолчанию, даже если сделать сериализацию можно немного.

Сериализация добавляет ограничения и потенциальные проблемы, поскольку совместимость структуры не застрахована. Хорошо, что по умолчанию он выключен.

Я должен признать, что видел очень мало нетривиальных классов, где стандартная сериализация делает то, что я хочу. Особенно в случае сложных структур данных. Таким образом, усилия, которые вы потратите на правильную сериализацию класса, значительно сократят затраты на добавление интерфейса.

9 голосов
/ 14 января 2009

Для некоторых классов, особенно тех, которые представляют что-то более физическое, такое как соединение File, Socket, Thread или DB, абсолютно бессмысленно сериализовать экземпляры. Для многих других сериализация может быть проблематичной, поскольку она разрушает ограничения уникальности или просто вынуждает вас иметь дело с экземплярами разных версий класса, чего вы, возможно, не хотите.

Возможно, было бы лучше сделать все сериализуемым по умолчанию и сделать классы не сериализуемыми через интерфейс ключевых слов или маркеров - но тогда те, кто должен использовать эту опцию, вероятно, не подумают об этом. Если вам нужно внедрить Serializable, вам скажет исключение.

4 голосов
/ 14 января 2009

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

3 голосов
/ 06 марта 2013

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

Источник: Почему классы должны реализовывать Serializable для записи в ObjectOutputStream? .

1 голос
/ 10 декабря 2014

Прочтите это, чтобы понять Serializable Interface и почему мы должны сделать только несколько классов Serializable, а также мы позаботимся о том, где использовать временное ключевое слово, если мы хотим удалить несколько полей из процедуры хранения.

http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/

1 голос
/ 14 января 2009

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

Просто полагаясь на стандартную поддержку сериализации в JVM, вы подвергаете себя всевозможным неприятным проблемам с версиями.

Уникальность, ссылки на «реальные» ресурсы, таймеры и множество других типов артефактов НЕ являются кандидатами на сериализацию.

0 голосов
/ 08 июля 2016

Класс, который необходимо сохранить в файле или другом носителе, должен реализовывать интерфейс Serializable, чтобы JVM могла разрешить сериализацию объекта класса. Почему класс Object не сериализован, тогда ни один из классов не должен реализовывать интерфейс, ведь JVM сериализует класс только тогда, когда я использую ObjectOutputStream , что означает, что элемент управления все еще в моих руках, чтобы позволить JVM сериализоваться.

Причина, по которой класс Object по умолчанию не сериализуем в том, что основной проблемой является версия класса. Поэтому каждый класс, который заинтересован в сериализации, должен быть явно помечен как Serializable и предоставить номер версии serialVersionUID.

Если serialVersionUID не указан, то при десериализации объекта мы получим неожиданные результаты, поэтому JVM выдает InvalidClassException , если serialVersionUID не соответствует. Поэтому каждый класс должен реализовывать интерфейс Serializable и предоставлять serialVersionUID , чтобы обеспечить идентичность класса, представленного на обоих концах.

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