Хеш-код как serialVersionUid
Я прочитал в статье, что по умолчанию serialVersionUid, предоставляемый JVM, является хеш-кодом объекта. Если мы не переопределим метод хеш-кода в классе, как будет вычисляться хеш-код во время десериализации, поскольку обычно хеш-код является адресом памяти объекта?
2 ответа
Я прочитал в статье, что по умолчанию
serialVersionUid
JVM предоставляет хеш-код объекта.
Это неверно. (Либо статья неверна, либо вы ее неправильно прочитали / неправильно поняли.)
UID серийной версии по умолчанию для сериализуемого класса полностью не связан с hashCode.
Алгоритм генерации UID серийной версии по умолчанию описан здесь:
По сути, он создает хеш SHA-1 из имени классов, модификаторов, имен интерфейсов и сигнатур своих полей, конструкторов и методов. Затем он берет первые 8 байтов хэша и собирает их в long
,
Я думаю, что вы не поняли. Это не hashcode
, serialVersionUid
является статической переменной и hashcode
это метод экземпляра и значение хеш-кода объекта изменяет объект на объект.
serialVersionUid
рассчитывается на основе структуры вашего класса - полей, методов и т. д. Это указано в http://download.oracle.com/javase/6/docs/platform/serialization/spec/serialTOC.html http://download.oracle.com/javase/6/docs/platform/serialization/spec/class.html для точного формата.
В спецификации описывается, что происходит без указания значения, но автогенерация использует тот же алгоритм.
Последовательность элементов в потоке следующая:
Название класса.
Модификаторы класса записываются как 32-разрядное целое число.
Название каждого интерфейса отсортировано по имени.
Для каждого поля класса, отсортированного по имени поля (кроме частных статических и частных переходных полей:
- Название поля.
- Модификаторы поля записываются как 32-разрядное целое число.
- Дескриптор поля.
Если инициализатор класса существует, запишите следующее:
- Название метода.
- Модификатор метода, java.lang.reflect.Modifier.STATIC, записывается как 32-разрядное целое число.
- Дескриптор метода, ()V.
Для каждого не приватного конструктора, отсортированного по имени метода и сигнатуре:
- Название метода.
- Модификаторы метода записаны как 32-разрядное целое число.
- Дескриптор метода.
Для каждого не закрытого метода, отсортированного по имени метода и сигнатуре:
- Название метода.
- Модификаторы метода записаны как 32-разрядное целое число.
- Дескриптор метода.
- Алгоритм SHA-1 выполняется в потоке байтов, созданных DataOutputStream, и выдает пять 32-битных значений sha[0..4]. Значение хеш-функции составляется из первого и второго 32-битных значений дайджеста сообщения SHA-1. Если результат дайджеста сообщения, пять 32-битных слов H0 H1 H2 H3 H4, находится в массиве из пяти значений типа int с именем sha, значение хеш-функции будет вычислено следующим образом:
long hash
= ((sha [0] >>> 24) & 0xFF) |((sha [0] >>> 16) & 0xFF) << 8 |
((sha [0] >>> 8) & 0xFF) << 16 |
((sha [0] >>> 0) & 0xFF) << 24 |
((sha [1] >>> 24) & 0xFF) << 32 |
((sha [1] >>> 16) & 0xFF) << 40 |
((sha [1] >>> 8) & 0xFF) << 48 |
((sha [1] >>> 0) & 0xFF) << 56;
Вот long hash
не упоминается hashcode