Ответ 1
Сериализация использует System.identityHashCode
(через IdentityHashMap
), чтобы гарантировать, что топология графа объекта, полученная в результате десериализации, топологически эквивалентна топологии входного графика.
Так как версия 8 Java имеет концепцию классов, основанных на значении. Это готовит будущую версию, которая, скорее всего, позволит определить типы значений. Оба определения/описания упоминают сериализацию (смелое лицо, добавленное мной):
О существующих классах, основанных на значении:
Программа может создавать непредсказуемые результаты, если она пытается отличить две ссылки от равных значений класса, основанного на значении, прямо через ссылочное равенство или косвенно через обращение к синхронизации, хеширование идентификаторов, сериализация, или любой другой чувствительный к идентификации механизм.
О будущих типах значений:
Хэш-код по умолчанию для объекта, доступный через System.identityHashCode, также не применяется к типам значений. Внутренние операции, такие как сериализация, которые делают различия объектов на основе идентификаторов, либо не будут применяться к значениям (поскольку они не применяются к примитивам), либо они будут использовать разницу на основе значений, предоставляемую типами значений hashCode метод.
Поскольку будущие реализации JVM могут не использовать заголовки объектов и ссылочные указатели для классов, основанных на значении, некоторые из ограничений ясны. (Например, не блокировать идентификатор, который JVM не должен поддерживать. Ссылка на которую заблокирована, может быть удалена и заменена другим позже, что делает освобождение блокировки бессмысленным и вызовет взаимоблокировки).
Но я не понимаю, как сериализация играет в это. Почему он считается "чувствительным к идентификации механизмом"? Почему это "делает различия между объектами на основе идентификаторов"?
Сериализация использует System.identityHashCode
(через IdentityHashMap
), чтобы гарантировать, что топология графа объекта, полученная в результате десериализации, топологически эквивалентна топологии входного графика.
Подумайте, что происходит, когда сериализуемый граф объектов имеет цикл. Алгоритм сериализации вводит бесконечный цикл в таком случае: если он не имеет определенного механизма для обнаружения и разрешения циклов. Мы все знаем, что Java-сериализация позволяет циклическим объектным графам, поэтому механизм существует.
Теперь рассмотрим определение цикла: граф содержит объект, который доступен из самого себя. Это определение относится к идентичности объекта, что означает, что механизм должен учитывать идентичность объекта для отслеживания циклов. На уровне реализации это достигается путем сохранения IdentityHashMap
всех видимых экземпляров, и этот класс полагается на Object.identityHashCode()
.
В приведенном вами предложении объясняется, как эта проблема будет решена в будущей версии Java: типы значений получат специальное лечение, так что обнаружение цикла будет полагаться на свои собственные методы equals
и hashCode
вместо ==
и identityHashCode
.