Почему классы Java на основе значений не должны быть сериализованы?

18

Так как версия 8 Java имеет концепцию на основе значений . Это готовит будущую версию, которая, скорее всего, позволит определить типы значений . Оба определения / описания упоминают сериализацию (смелое лицо, добавленное мной):

О существующих классах, основанных на значении:

  

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

О будущих типах значений:

  

Хэш-код по умолчанию для объекта, доступный через System.identityHashCode, также не применяется к типам значений. Внутренние операции, такие как сериализация , которые делают различия объектов на основе идентификаторов, либо не будут применяться к значениям (поскольку они не применяются к примитивам), либо они будут использовать дифференциал на основе значений, предоставляемый хэш-кодом типа значения метод.

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

Но я не понимаю, как сериализация играет в это. Почему он считается "чувствительным к идентификации механизмом" ? Почему «делает различия объектов на основе идентификаторов» ?

    
задан Nicolai 19.10.2014 в 16:37
источник
  • Фактический вопрос и вопрос в теме полностью различны. –  Chris311 01.03.2018 в 09:14

2 ответа

12

Сериализация использует System.identityHashCode (через IdentityHashMap ), чтобы гарантировать, что топология графа объекта, полученная в результате десериализации, топологически эквивалентна топологии входного графика.     

ответ дан Brian Goetz 19.10.2014 в 17:12
  • Это моя точка - идентичность в первую очередь относится к алгоритмам графа для сохранения топологии; т.е. избегать циклирования циклов. –  Thomas W 17.02.2015 в 04:48
  • В этом ответе указывается, почему идентичность может играть роль в процессе десериализации. Однако я не понимаю, почему это означает, что «классы, основанные на значении [должны] не быть сериализованы», что, кажется, является исходным вопросом. (Даже если OP, похоже, удовлетворен ответом.) –  Michael Piefel 29.08.2016 в 17:30
  • Что было бы альтернативой этому? Как бы я сериализовал объект, у которого есть поле localdate –  jtkSource 19.03.2017 в 10:26
  • Кроме того, если это так, то зачем делать LocalDate Serializable? –  jtkSource 19.03.2017 в 10:38
  • Почему LocalDateTime реализует Serializable? –  Andremoniy 18.12.2017 в 10:51
3

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

Теперь рассмотрим определение цикла: граф содержит объект, который доступен из самого себя. Это определение относится к объекту identity , что означает, что механизм должен учитывать идентичность объекта для отслеживания циклов. На уровне реализации это достигается за счет сохранения IdentityHashMap всех увиденных экземпляров, и этот класс полагается на Object.identityHashCode() .

В приведенном вами предложении объясняется, как эта проблема будет решена в будущей версии Java: типы значений получат специальное обращение, так что обнаружение цикла будет полагаться на свои собственные методы equals и hashCode вместо == и identityHashCode .

    
ответ дан Marko Topolnik 19.10.2014 в 17:21