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

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

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

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

    a) Как преобразовать эту строку в двоичный?

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

alt text

Ответ 1

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

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

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

Ответ 2

Можно использовать 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 :       [email protected]
Address: 0x7aae62270

Заключение:

  • hashcode!= адрес
  • toString = class @HEX (hashcode)

Ответ 3

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

Ответ 4

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

где

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

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

Ответ 5

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

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

Важно понимать, что все, что вы делаете в Java, обрабатывается виртуальной машиной Java. Эта информация дает JVM. То, что на самом деле происходит в ОЗУ операционной системы хоста, полностью зависит от реализации JRE.

Ответ 7

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

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

Ответ 8

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

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

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

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

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

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

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

Ответ 9

toString() - это функция в библиотеке java.lang.Object, которая возвращает String-представление ссылки Object, тело toString() выглядит следующим образом

public String toString(Object arg)
{
    return "[email protected]";
}

здесь адрес указан JVM, а не OS

вы можете переопределить функцию toString(), предоставив свою собственную реализацию в теле функции