Почему Java не нужна интерфейс Serializable?

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

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

что я упустил?

13 ответов


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

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

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

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

сделать все классы сериализуемыми усугубит эти проблемы. Проверьте Эффективное Второе Издание Java, в частности пункт 74: реализовать Serializable рассудительно.


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

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

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

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


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


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

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

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


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

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


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


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

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


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

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

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


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

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


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

Итак, что вам в принципе нужно сделать, это прочитать все свойства вашего 3-го класса. Или, если это вариант для вас: декомпилировать, поместить проклятое ключевое слово туда и перекомпилировать.


есть некоторые вещи в Java, которые просто не могут сериализоваться, потому что они специфичны для среды выполнения. Вещи как потоки, потоки выполнения, так далее. и даже некоторые классы GUI (которые подключены к базовой ОС) не могут быть сериализован.


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


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

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

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