Адреса пам'яті змінних на Java


139

Будь ласка, подивіться на малюнок нижче. Коли ми створюємо об’єкт в java з newключовим словом, ми отримуємо адресу пам'яті з ОС.

Коли ми пишемо, out.println(objName)ми можемо бачити "спеціальний" рядок як вихід. Мої запитання:

  1. Що це за вихід?
  2. Якщо це адреса пам'яті, яку нам дала ОС:

    а) Як я можу перетворити цей рядок у двійковий?

    b) Як я можу отримати одну цілу адресу змінних?

alt текст


5
добре, я не голосую проти, тому що питання досить чітке, лише пропозиція про те, щоб ви мали це зробити в тексті, щоб люди могли його шукати
phunehehe

2
Використовуючи sun.misc.Unsafe можна отримати адресу об’єкта java. Для переліку програм дивіться: javapapers.com/core-java/address-of-a-java-object
Джозеф Куландай

загострене значення - це шістнадцяткове зображення хеш-коду об'єкта a1 & a2
Naveen

Відповіді:


166

Це ім'я класу та System.identityHashCode (), розділене символом '@'. Те, що представляє хеш-код ідентичності, залежить від реалізації. Це часто є початковою адресою пам’яті об’єкта, але об’єкт може переміщуватися в пам’яті VM з часом. Тож (коротко) ви не можете розраховувати на те, що це щось.

Отримання пам’яті адрес змінних в Java не має сенсу, оскільки JVM може вільно реалізовувати об’єкти та переміщувати їх так, як здасться потрібним (ваші об’єкти можуть / рухатимуться під час збирання сміття тощо)

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


33
Ще один цікавий момент - не гарантується, що хеш-коди ідентичності є унікальними. Наприклад, на 64-розрядному JVM є 2 ^ 32 ідентифікаційні хеш-коди, але 2 ^ 64 адреси пам'яті .
Алекс Жасмін

11
Насправді ідентифікаційний хеш-код не може змінитися , інакше договір hashCode () буде порушений.
Метт Макенрі

1
Я використовую це для реєстрації / налагодження для визначення в журналах, коли об’єкти вказують на один і той же об'єкт замість еквівалентних. Для цих цілей identityHashcodeце не є безглуздим, просто не є надійним. :)
Sled

@BrianAgnew: Я хочу знати -> Чому два об'єкти мають однаковий хеш-код. Я розгублений, тому що в c або c ++ я дізнався, що кожна змінна або об'єкт мають різні місця в пам'яті. Тоді в java Як можна ідентифікувати або диференціювати два об'єкти з однаковим хеш-кодом.
Вед Пракаш

1
@VedPrakash, хеш-код об'єкта дозволяє зберігати об'єкти у хешованих колекціях. Якщо ви хочете розмежувати два різні об’єкти, ви можете просто використати еталону рівність
Брайан Агнев

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

Це не пам'ять адреси Це ім'я класу @ хеш-код

де

classname = повне кваліфіковане ім'я або абсолютне ім’я (тобто ім'я пакета, а потім ім'я класу)

хеш-код = шістнадцятковий формат (System.identityHashCode (obj) або obj.hashCode () дасть вам хеш-код у десятковому форматі)


4

Як сказала Суніл, це не адреса пам'яті . Це просто хеш-код

Щоб отримати той самий @ вміст, ви можете:

Якщо hashCode не буде замінено у цьому класі:

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

Якщо hashCode буде замінено, ви отримаєте початкове значення за допомогою:

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

Це часто плутають з адресою пам'яті, тому що якщо ви не перекриєте hashCode (), адреса пам'яті використовується для обчислення хеша.


1

Те, що ви отримуєте, є результатом методу toString () класу Object або, точніше, ідентичностіHashCode (), як вказав uzay95.

"Коли ми створюємо об'єкт в Java з новим ключовим словом, ми отримуємо адресу пам'яті з ОС."

Важливо усвідомити, що все, що ви робите на Java, обробляє віртуальна машина Java. Саме СП надає цю інформацію. Те, що насправді відбувається в оперативній пам’яті операційної системи хоста, повністю залежить від впровадження JRE.



0

У Java, коли ви створюєте об'єкт з класу типу Person p = new Person();, pнасправді є адресою пам'яті, яка вказує на тип Person.

Коли ви використовуєте параметр statemenet для друку, pви побачите адресу. newКлючове слово робить нову пам'ять , яка містить всі змінні екземпляра і методи , які включені в class Personі pє базовою змінною вказує на цю комірку пам'яті.


на малюнку a1 і a2 два різні адреси пам'яті. Це є причиною отримання двох різних значень.
Panduka Wedisinghe
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.