Адрес памяти переменных в Java - PullRequest
123 голосов
/ 25 декабря 2009

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

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

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

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

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

alt text

Ответы [ 8 ]

144 голосов
/ 25 декабря 2009

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

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

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

30 голосов
/ 19 декабря 2013

Это возможно с помощью 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 (хэш-код)

11 голосов
/ 25 декабря 2009

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

5 голосов
/ 18 декабря 2013

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

, где

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

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

2 голосов
/ 09 августа 2016

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

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

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

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

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

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

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

1 голос
/ 01 января 2016

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

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

1 голос
/ 25 декабря 2009

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

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

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

0 голосов
/ 20 апреля 2015

это полезно знать о хэш-коде в Java:

http://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/

...