Мы много работаем с сериализацией, и необходимость указывать тег Serializable для каждого используемого объекта является своего рода бременем. Особенно, когда это сторонний класс, который мы не можем изменить.
Возникает вопрос: поскольку Serializable - это пустой интерфейс, а Java обеспечивает надежную сериализацию после добавления, implements Serializable
почему они не сделали все сериализуемым и все?
Что мне не хватает?
java
serialization
Йони Ройт
источник
источник
Ответы:
Сериализация чревата подводными камнями. Поддержка автоматической сериализации этой формы делает внутренние компоненты класса частью общедоступного API (поэтому javadoc предоставляет вам постоянные формы классов ).
Для долгосрочного сохранения класс должен иметь возможность декодировать эту форму, что ограничивает изменения, которые вы можете внести в дизайн класса. Это нарушает инкапсуляцию.
Сериализация также может привести к проблемам с безопасностью. Имея возможность сериализовать любой объект, на который он ссылается, класс может получить доступ к данным, которые он обычно не мог бы получить (путем анализа полученных байтовых данных).
Есть и другие проблемы, например, недостаточно четкое определение сериализованной формы внутренних классов.
Создание сериализуемых классов усугубит эти проблемы. Ознакомьтесь с « Эффективным вторым изданием Java» , в частности с правилом 74: разумно реализуйте Serializable .
источник
Я думаю, что на этот раз люди как Java, так и .Net ошиблись, было бы лучше сделать все сериализуемым по умолчанию и вместо этого нужно было бы отмечать только те классы, которые нельзя безопасно сериализовать.
Например, в Smalltalk (язык, созданный в 70-х годах) каждый объект по умолчанию сериализуем. Я понятия не имею, почему это не так в Java, учитывая тот факт, что подавляющее большинство объектов безопасно сериализовать, а лишь некоторые из них - нет.
Пометка объекта как сериализуемого (с интерфейсом) не делает этот объект волшебным образом сериализуемым, он был сериализуемым все время, просто теперь вы выразили то, что система могла бы найти самостоятельно, поэтому я не вижу серьезных причин для сериализация такая, как сейчас.
Я думаю, что либо дизайнеры приняли плохое решение, либо сериализация была запоздалой мыслью, либо платформа никогда не была готова выполнять сериализацию по умолчанию для всех объектов безопасно и последовательно.
источник
Serializable
трюк - еще одно неправильное решение, которое было принято десять или два года назад, и еще одно добавление к раздражению при работе с чистой java, например, некоторые недостатки в сборе и обработке строк в стандартной библиотеке. К счастью, есть Крио, но это зависимость, и ее нужно сначала найти. Вот как должна была выполняться встроенная сериализация.Не все действительно сериализуемо. Возьмем, к примеру, подключение к сетевому сокету. Вы можете сериализовать данные / состояние вашего объекта сокета, но суть активного соединения будет потеряна.
источник
implements NotSerializable
:)Основная роль Serializable в Java - сделать по умолчанию все другие объекты несериализуемыми. Сериализация - очень опасный механизм, особенно в его реализации по умолчанию. Следовательно, как и дружба в C ++, он отключен по умолчанию, даже если сделать вещи сериализуемыми стоит немного.
Сериализация добавляет ограничения и потенциальные проблемы, поскольку совместимость структур не гарантируется. Хорошо, что по умолчанию он выключен.
Должен признать, что встречал очень мало нетривиальных классов, в которых стандартная сериализация делает то, что я хочу. Особенно в случае сложных структур данных. Таким образом, усилия, которые вы бы потратили на правильную сериализацию классов, значительно уменьшают затраты на добавление интерфейса.
источник
Для некоторых классов, особенно тех, которые представляют что-то более физическое, например, файл, сокет, поток или соединение с БД, сериализация экземпляров не имеет абсолютно никакого смысла. Для многих других сериализация может быть проблематичной, потому что она разрушает ограничения уникальности или просто заставляет вас иметь дело с экземплярами разных версий класса, чего вы, возможно, не захотите.
Возможно, было бы лучше сделать все сериализуемым по умолчанию и сделать классы несериализуемыми с помощью интерфейса ключевого слова или маркера, но тогда те, кто должен использовать эту опцию, вероятно, не подумают об этом. Таким образом, если вам нужно реализовать Serializable, вам об этом сообщит исключение.
источник
Я думаю, это было сделано для того, чтобы вы, как программист, знали, что ваш объект может быть сериализован.
источник
По-видимому, в некоторых предварительных проектах все было сериализуемым, но из соображений безопасности и правильности окончательный дизайн закончился, как мы все знаем.
Источник: Почему классы должны реализовывать Serializable, чтобы их можно было записать в ObjectOutputStream? .
источник
При необходимости явно указать, что экземпляры определенного класса являются сериализуемыми, язык заставляет вас задуматься, следует ли вам это разрешить. Для простых объектов-значений сериализация тривиальна, но в более сложных случаях вам нужно действительно все продумать.
Просто полагаясь на стандартную поддержку сериализации JVM, вы подвергаете себя всевозможным неприятным проблемам с версией.
Уникальность, ссылки на «реальные» ресурсы, таймеры и множество других типов артефактов НЕ являются кандидатами на сериализацию.
источник
Прочтите это, чтобы понять сериализуемый интерфейс и почему мы должны сделать только несколько классов сериализуемыми, а также мы позаботимся о том, где использовать временное ключевое слово, если мы хотим удалить несколько полей из процедуры сохранения.
http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/
источник
Что ж, я отвечаю, что это без уважительной причины. И из ваших комментариев я вижу, что вы это уже узнали. Другие языки с радостью пытаются сериализовать все, что не прыгает по дереву после того, как вы посчитали до 10. Объект по умолчанию должен быть сериализуемым.
Итак, что вам в основном нужно сделать, так это самому прочитать все свойства вашего стороннего класса. Или, если это для вас вариант: декомпилируйте, вставьте туда чертово ключевое слово и перекомпилируйте.
источник
В Java есть некоторые вещи, которые просто невозможно сериализовать, потому что они зависят от времени выполнения. Такие вещи, как потоки, потоки, среда выполнения и т. Д., И даже некоторые классы графического интерфейса (которые подключены к базовой ОС) не могут быть сериализованы.
источник
Хотя я согласен с пунктами, изложенными в других ответах здесь, настоящая проблема связана с десериализацией: если определение класса изменится, существует реальный риск, что десериализация не сработает. Никогда не изменять существующие поля - довольно серьезное обязательство для автора библиотеки! Поддержание совместимости API - это и так достаточно рутинная работа.
источник
Класс, который необходимо сохранить в файле или другом носителе, должен реализовывать интерфейс Serializable, чтобы JVM могла позволить сериализацию объекта класса. Почему класс Object не сериализуется, тогда ни один из классов не должен реализовывать интерфейс, ведь JVM сериализует класс только тогда, когда я использую ObjectOutputStream, что означает, что элемент управления все еще находится в моих руках, чтобы позволить JVM сериализоваться.
Причина, по которой класс Object не может быть сериализован по умолчанию, заключается в том, что версия класса является основной проблемой. Поэтому каждый класс, который заинтересован в сериализации, должен быть явно помечен как Serializable и предоставить номер версии serialVersionUID.
Если serialVersionUID не указан, мы получаем неожиданные результаты при десериализации объекта, поэтому JVM выдает исключение InvalidClassException, если serialVersionUID не совпадает. Поэтому каждый класс должен реализовать интерфейс Serializable и предоставить serialVersionUID, чтобы убедиться, что класс, представленный на обоих концах, идентичен.
источник