Реализация hashCode () по умолчанию для объектов Java



Я пытался понять хэш-код () для объекта Java и увидел следующий код для метода hashCode () объекта Java:



package java.lang;
public class Object {

// Some more code

public native int hashCode();

// Some other code

}


Теперь мы знаем, что если мы создаем класс, он неявно расширяет класс объектов, и для этого я написал примерный пример:

package com.example.entity;
public class FirstClass {
private int id;
private String name;
// getters and setters
}


Таким образом, этот класс, а именно: FirstClass, будет неявно расширять класс Object.



Основной класс:



package com.example.app.main;
import com.example.entity.FirstClass;
public class MainApp {
public static void main(String[] args) {
FirstClass fs = new FirstClass();
fs.setId(1);
fs.setName("TEST");
System.out.println("The hasCode for object fs is " + fs.hashCode());
}
}


Поскольку FirstClass расширяет Object класс неявно, следовательно, он будет иметь Object классы ' hashCode() метод.



Я вызвал hashCode() на FirstClass объекте , и поскольку я не переопределил hashCode(), теоретически он должен вызвать Object класс hashCode().



Мое сомнение:



Поскольку класс объектов не имеет никакой реализации, как он может вычислить хэш-код для любого объекта?



В моем случае, когда я запускал программу, хэш-код, который она возвращала, был 366712642.

Может ли кто - нибудь помочь мне понять это?
683   3  

3 ответов:

Хотя здесь есть некоторые ответы, утверждающие, что реализация по умолчанию основана на "памяти", это явно неправильно. Это не так уже много лет.

В java-8 вы можете сделать:

java -XX:+PrintFlagsFinal | grep hashCode

, чтобы получить точный алгоритм, который используется (5 по умолчанию).

  0 == Lehmer random number generator, 
  1 == "somehow" based on memory address
  2 ==  always 1
  3 ==  increment counter 
  4 == memory based again ("somehow")
  5 == read below

По умолчанию (5) он использует алгоритм Marsaglia XOR-Shift, который не имеет ничего общего с памятью.

Это не очень трудно доказать, если вы сделаете:

 System.out.println(new Object().hashCode());

Несколько раз, в новой виртуальной машине все время-вы получите одно и то же значение, поэтому Marsaglia XOR-Shift начинается с семени (всегда одно и то же, если только какой-то другой код не изменяет его) и работает от этого.

Но даже если вы переключаетесь на некоторый хэш-код, основанный на памяти, и объекты потенциально перемещаются (вызовы сборщика мусора), как вы гарантируете, что тот же хэш-код будет взят после того, как GC переместил этот объект? Подсказка: indentityHashCode и заголовки объектов.

Вы все неправильно поняли:

public native int hashCode();

Не означает, что нет реализации. Это просто означает, что метод реализован вродной aka C/C++ части JVM. Это означает, что вы не можете найти исходный код Java для этого метода. Но где-то в JVM все еще есть некоторый код, который вызывается всякий раз, когда вы вызываете hashCode() на каком-то объекте.

И как объясняет другой ответ: что реализация "default" использовала адрес" memory" базовые объекты. Дело в том, что использование java означает, что нет знания "адресов памяти". Имейте в виду: JVM написан на C/C++ - и реальное управление памятью происходит в этих собственных частях JVM.

Другими словами: Вы не можете написать Java-код, который сообщает вам о "собственном адресе памяти" объекта.

Но как ясно из другого ответа Юджина: хэш, связанный с "расположением памяти", - это дело прошлого.

Реализация хэш-кода по умолчанию в классе объектов - это адрес памяти объекта в шестнадцатеричном формате. JVM призывает к реализации этого.

Некоторые полезные ссылки:

Https://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html

Comments

    Ничего не найдено.