Подтвердить что ты не робот

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

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