Адрес памяти переменных в Java


139

Пожалуйста, посмотрите на картинку ниже. Когда мы создаем объект в Java с newключевым словом, мы получаем адрес памяти из ОС.

Когда мы пишем, out.println(objName)мы можем видеть «специальную» строку в качестве вывода. Мои вопросы:

  1. Что это за выход?
  2. Если это адрес памяти, который нам предоставляет ОС:

    а) Как я могу преобразовать эту строку в двоичный файл?

    б) Как я могу получить один адрес целочисленных переменных?

альтернативный текст


5
ну, я не голосую вниз, потому что вопрос достаточно ясен, просто предположение, что вы должны были сделать это в тексте, чтобы люди могли его искать
phunehehe

2
Используя sun.misc.Unsafe, можно получить адрес объекта Java. Список программ см. По адресу
Джозеф Куландай,

указанное значение является шестнадцатеричным представлением хеш-кода объекта a1 & a2
Naveen

Ответы:


167

Это имя класса и System.identityHashCode (), разделенные символом «@». То, что представляет собой идентификационный хеш-код, зависит от реализации. Часто это начальный адрес памяти объекта, но со временем объект может быть перемещен в память виртуальной машиной. Так что (кратко) вы не можете полагаться на то, что это что-то.

Получение адресов памяти переменных не имеет смысла в Java, так как JVM может свободно реализовывать объекты и перемещать их так, как кажется (ваши объекты могут / будут перемещаться во время сбора мусора и т. Д.)

Integer.toBinaryString () даст вам целое число в двоичной форме.


33
Еще одним интересным моментом является то, что хэш-коды идентичности не гарантируются быть уникальными. Например, на 64-битной JVM существует 2 ^ 32 идентификатора хеш-кода, но 2 ^ 64 адреса памяти .
Алекс Жасмин

11
На самом деле хэш-код идентичности не может быть изменен , в противном случае контракт hashCode () будет нарушен.
Мэтт МакГенри

1
Я использую это для регистрации / отладки для определения в журналах, когда объекты указывают на один и тот же объект вместо эквивалентных. Для этих целей identityHashcodeэто не бессмысленно, это просто не надежно. :)
Сани

@BrianAgnew: я хочу знать -> Почему два объекта имеют одинаковый хэш-код. Я сбит с толку, потому что я узнал в c или c ++, что каждая переменная или объект имеют различное расположение в памяти. Затем в Java Как можно идентифицировать или дифференцировать два объекта с одинаковым hashCode.
Вед Пракаш

1
@VedPrakash хеш-код объекта позволяет хранить объекты в хешированных коллекциях. Если вы хотите различать два разных объекта, вы можете просто использовать ссылочное равенство
Brian Agnew

36

Это возможно с помощью sun.misc.Unsafe: см. Этот замечательный ответ от @Peter Lawrey -> Есть ли способ получить ссылочный адрес?

Используя его код для printAddresses ():

    public static void printAddresses(String label, Object... objects) {
    System.out.print(label + ": 0x");
    long last = 0;
    int offset = unsafe.arrayBaseOffset(objects.getClass());
    int scale = unsafe.arrayIndexScale(objects.getClass());
    switch (scale) {
    case 4:
        long factor = is64bit ? 8 : 1;
        final long i1 = (unsafe.getInt(objects, offset) & 0xFFFFFFFFL) * factor;
        System.out.print(Long.toHexString(i1));
        last = i1;
        for (int i = 1; i < objects.length; i++) {
            final long i2 = (unsafe.getInt(objects, offset + i * 4) & 0xFFFFFFFFL) * factor;
            if (i2 > last)
                System.out.print(", +" + Long.toHexString(i2 - last));
            else
                System.out.print(", -" + Long.toHexString( last - i2));
            last = i2;
        }
        break;
    case 8:
        throw new AssertionError("Not supported");
    }
    System.out.println();
}

Я настроил этот тест:

    //hashcode
    System.out.println("Hashcode :       "+myObject.hashCode());
    System.out.println("Hashcode :       "+System.identityHashCode(myObject));
    System.out.println("Hashcode (HEX) : "+Integer.toHexString(myObject.hashCode()));

    //toString
    System.out.println("toString :       "+String.valueOf(myObject));

    printAddresses("Address", myObject);

Вот вывод:

Hashcode :       125665513
Hashcode :       125665513
Hashcode (HEX) : 77d80e9
toString :       java.lang.Object@77d80e9
Address: 0x7aae62270

Вывод :

  • хэш-код! = адрес
  • toString = class @ HEX (хэш-код)

13

Это результат реализации объекта toString (). Если ваш класс переопределяет toString (), он напечатает что-то совершенно другое.


6

Это не адрес памяти Это имя класса @ hashcode

где

имя класса = полное имя или абсолютное имя (т.е. имя пакета, за которым следует имя класса)

hashcode = шестнадцатеричный формат (System.identityHashCode (obj) или obj.hashCode () даст вам хеш-код в десятичном формате)


4

Как сказал Сунил, это не адрес памяти. Это просто хеш-код

Чтобы получить тот же @ контент, вы можете:

Если hashCode не переопределен в этом классе:

"@" + Integer.toHexString(obj.hashCode())

Если hashCode переопределен, вы получите исходное значение с помощью:

"@" + Integer.toHexString(System.identityHashCode(obj)) 

Это часто путают с адресом памяти, потому что если вы не переопределите hashCode (), адрес памяти используется для вычисления хеша.


1

То, что вы получаете, является результатом метода toString () класса Object или, точнее, identityHashCode (), как указал uzay95.

«Когда мы создаем объект в Java с новым ключевым словом, мы получаем адрес памяти из ОС».

Важно понимать, что все, что вы делаете в Java, обрабатывается виртуальной машиной Java. Именно JVM предоставляет эту информацию. Что на самом деле происходит в оперативной памяти хост-операционной системы, полностью зависит от реализации JRE.



0

В Java, когда вы создаете объект из класса like Person p = new Person();, pна самом деле это адрес ячейки памяти, который указывает на тип Person.

При использовании Statemenet для печати pвы увидите адрес. newКлючевое слово делает новую память , содержащую все переменные экземпляра и методы , которые включены в class Personи pявляется базовой переменной указывает на эту ячейку памяти.


на вашей картинке a1 и a2 - два разных адреса памяти. Вот причина получения двух разных значений.
Пандука Ведизинге
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.