объект Java.константа результата hashCode () во всех JVMs/системах?
выход Object.hashCode()
требуется быть одинаковым для всех реализаций JVM для одного и того же объекта?
например, если "test".hashCode()
возвращает 1
на 1.4, может ли он потенциально вернуться 2
работает на 1.6. Или что, если операционные системы были разными, или между экземплярами была другая архитектура процессора?
6 ответов
нет. Выход hashCode
может меняться между реализациями JVM и даже между различными исполнениями программы на одном JVM.
однако, в конкретном примере, который вы привели, стоимостью "test".hashCode()
будет на самом деле, быть последовательным, потому что реализация hashCode
на String
объекты являются частью API String
(см. Javadocs для java.ленг.Строка и этот другой так пост).
из API
генеральный контракт хэш-кода:
- всякий раз, когда он вызывается на одном и том же объекте более одного раза во время выполнения приложения Java, метод hashCode должен последовательно возвращать одно и то же целое число, при условии, что никакая информация, используемая в равных сравнениях на объекте, не изменяется. Это целое число не должно оставаться последовательным от одного выполнения приложения к другому выполнению того же приложения.
- если два объекта равны согласно Equals(Object) метод, затем вызывая метод hashCode на каждом из двух объектов должен привести к тому же самому целочисленному результату.
- не требуется, чтобы, если два объекта неравны в соответствии с равными (java.ленг.Object) метод, затем вызывая метод hashCode на каждом из двух объектов должен привести к отличным целочисленные результаты. Однако программист должен знать, что получение различных целочисленных результатов для неравных объектов может повысить производительность коллекция Hashtable.
насколько это разумно практично, метод hashCode, определенный объектом класса, возвращает различные целые числа для различных объектов. (Это обычно реализуется путем преобразования внутренний адрес объекта в целое число, но этот метод реализации не требуется на языке программирования javatm.)
нет, результат hashCode()
is только константа во время одного выполнения. Вы не должны ожидать, что результат функции будет одинаковым между исполнениями, не говоря уже о версиях JRE или платформах.
прежде всего, результат хэш-кода сильно зависит от типа объекта и его реализации. каждый класс, включая его подклассы, может определять свое собственное поведение. вы можете положиться на него после генерального контракта, как указано в javadoc, а также в других ответах. но значение не обязательно должно оставаться неизменным после перезапуска виртуальной машины. особенно если это зависит от .реализации хэш-кода классов thrid party.
при упоминании конкретной реализации Класс String, вы не должны зависеть от возвращаемого значения. если программа запущена в другой виртуальной машине, это может измениться.
Если вы ссылаетесь исключительно на Sun Vm, можно утверждать, что Sun не сломает - даже плохо запрограммированный - существующий код. поэтому "тест".hashCode () всегда будет возвращать ровно 3556498 для любой версии Sun VM.
Если вы хотите преднамеренно выстрелить себе в ногу, идите вперед и полагайтесь на это. люди, которые должны исправьте свой код, запущенный на "2015 Nintendo Java VM для феном", будет выкрикивать ваше имя ночью.
Как уже отмечалось, для многих реализаций поведение по умолчанию hashCode () должно возвращать адрес объекта. Очевидно, что это может быть по-разному каждый раз, когда программа запускается. Это также согласуется с поведением equals () по умолчанию: два объекта равны, только если они являются одним и тем же объектом (где x и y оба ненулевые, x).равно (y) тогда и только тогда, когда x == y).
для любых классов, где переопределены hashCode() и equals (), как правило, они вычисляются в детерминированный способ, основанный на значениях некоторых или всех членов. Таким образом, на практике вполне вероятно, что если объект в одном запуске программы можно сказать равным объекту в другом запуске программы, и исходный код тот же (включая такие вещи, как исходный код для строки.hashCode() если это вызывается переопределением hashCode (), хэш-коды будут одинаковыми.
Это не гарантируется, хотя трудно придумать разумный реальный пример.
единственная правда: хэш-код одинаковый для запуска приложения. Другой прогон может дать другие хэш-коды.
когда вы спрашиваете хэш-код объекта, JVM создает его с помощью одного из алгоритмов RNG и помещает его в заголовок объекта для будущего использования. Просто посмотрите в get_next_hash функция в OpenJDK.
алгоритм RNG настраивается с помощью JVM arg - XX: hashCode=x, где x-цифра:
0 – Park-Miller RNG (по умолчанию)
1-f (адрес, глобальный)
2 – Константа 1
3 – последовательного счетчика
4 – адрес объекта в куче
5 – Xorshift (самый быстрый)
когда хэш-код равен адресу в куче-это иногда неудобно, потому что GC может перемещать объекты в другие ячейки кучи и т. д.