Можно ли сериализовать объекты на основе значений, если приложение никогда не полагается на идентификатор своего объекта?

Сонар показывает

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

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

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


person sagar    schedule 21.12.2017    source источник


Ответы (1)


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

Если разработчик объявляет класс на основе значений и реализует Serializable, он предполагает, что классы на основе значений и сериализация совместимы и останутся таковыми.

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

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

person Holger    schedule 21.12.2017
comment
мой маленький мозг не переваривает это, поэтому в основном мы говорим, что это типы значений + они реализуют Serializable => никогда не полагаются на свою идентичность (через ==?), вместо этого используйте equals? - person Eugene; 21.12.2017
comment
@Eugene: всегда использование equals вместо == применяется к типам значений в целом. Теперь сериализация сохраняет и восстанавливает удостоверения, используя обратные ссылки на уже встреченные объекты, но, поскольку типы значений имеют неопределенное удостоверение, вы не должны полагаться на это. Будущие версии могут вести себя так, как если бы использовались writeUnshared, но возможно и обратное: одинаковые значения могут стать идентичными экземплярами (если вы считаете их неподвижными объектами)… - person Holger; 21.12.2017
comment
спасибо, что не давали мне спать до 3 часов ночи, читая эти проблемы с сериализацией (если бы только SO мог оплачивать мои счета напрямую...). Итак, если я сериализую два экземпляра (которые являются equals, но не ==) Optional сегодня, я буду писать два разных экземпляра; в мире типов значений я бы написал только один. Но поскольку они неизменны, почему это имеет значение? Не похоже, что вы можете получить потерянное обновление через writeObject двух последовательных записей? Я надеюсь, что здесь есть смысл - person Eugene; 22.12.2017
comment
@Евгений: не совсем так. В мире типов значений вы пишете не экземпляры, а значения, поэтому термины «разные экземпляры» или «один и тот же экземпляр» становятся бессмысленными. Подумайте об этом так: необязательный элемент — это инкапсулированная ссылка (если она не пуста). Таким образом, запись необязательного параметра означает «записать эту ссылку и некоторую метаинформацию, чтобы восстановить ее в Optional». Чтение этой информации будет эквивалентно чтению ссылки и вызову Optional.of(…), который может создать или не создать один и тот же экземпляр для одной и той же ссылки, хотя «в мире типов значений» «тот же экземпляр» снова бессмысленно… - person Holger; 22.12.2017
comment
@Eugene: Но не забывайте, Optional не сериализуем, поэтому давайте вместо этого рассмотрим один элемент List.of(…) - person Holger; 22.12.2017