web-dev-qa-db-de.com

Speicheradresse von Variablen in Java

Bitte sehen Sie sich das Bild unten an .. Wenn wir ein Objekt mit neuem Schlüsselwort in Java erstellen, erhalten wir eine Speicheradresse vom Betriebssystem.

Wenn wir out.println(objName) schreiben, sehen wir eine "spezielle" Zeichenfolge als Ausgabe. Meine Fragen sind:

  1. Was ist diese Ausgabe?
  2. Wenn es sich um eine Speicheradresse handelt, die uns das Betriebssystem gegeben hat:

    a) Wie kann ich diesen String in eine Binärdatei konvertieren?

    b) Wie kann ich eine ganzzahlige Variablenadresse erhalten?

alt text

121
uzay95

Dies ist der Klassenname und System.identityHashCode () , getrennt durch das Zeichen '@'. Was der Identitäts-Hash-Code darstellt, ist implementierungsspezifisch. Es ist oft die anfängliche Speicheradresse des Objekts, aber das Objekt kann von der VM mit der Zeit in den Speicher verschoben werden. (Kurz) Sie können sich also nicht darauf verlassen, dass es etwas ist.

Das Abrufen der Speicheradressen von Variablen ist in Java bedeutungslos, da es der JVM frei ist, Objekte zu implementieren und sie nach Belieben zu verschieben (Ihre Objekte bewegen sich möglicherweise während der Speicherbereinigung usw.).

Integer.toBinaryString () gibt Ihnen eine Ganzzahl in binärer Form.

141
Brian Agnew

Es ist möglich, Sun.misc.Unsafe: Diese großartige Antwort von @Peter Lawrey zu sehen -> Gibt es eine Möglichkeit, eine Referenzadresse zu erhalten?

Verwenden des Codes für 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();
}

Ich habe diesen Test eingerichtet:

    //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);

Hier ist die Ausgabe:

Hashcode :       125665513
Hashcode :       125665513
Hashcode (HEX) : 77d80e9
toString :       [email protected]
Address: 0x7aae62270

Fazit :

  • hashcode! = Adresse
  • toString = class @ HEX (Hashcode)
27
JBE

Dies ist die Ausgabe der Object-Implementierung "toString ()". Wenn Ihre Klasse toString () überschreibt, wird etwas völlig anderes gedruckt.

11
Paul Tomblin

Dies ist keine Speicheradresse Dies ist Klassenname @ Hashcode

woher 

klassenname = vollqualifizierter Name oder absoluter Name (dh Paketname gefolgt von Klassenname)

hashcode = Hexadezimal-Format (System.identityHashCode (obj) oder obj.hashCode () gibt den Hashcode im Dezimalformat aus)

5

Wie Sunil sagte, ist dies nicht Speicheradresse Dies ist nur der Hashcode

Um den gleichen @ Inhalt zu erhalten, können Sie:

Wenn hashCode in dieser Klasse nicht überschrieben wird:

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

Wenn hashCode überschrieben wird, erhalten Sie den ursprünglichen Wert mit:

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

Dies wird oft mit der Speicheradresse verwechselt, denn wenn Sie hashCode () nicht überschreiben, wird die Speicheradresse zur Berechnung des Hashs verwendet.

2
Topera

Was Sie erhalten, ist das Ergebnis der toString () - Methode der Object-Klasse oder genauer der identityHashCode (), wie uzay95 darauf hingewiesen hat.

"Wenn wir in Java ein Objekt mit einem neuen Schlüsselwort erstellen, erhalten wir eine Speicheradresse vom Betriebssystem."

Es ist wichtig zu wissen, dass alles, was Sie in Java tun, von der Java Virtual Machine erledigt wird. Es ist die JVM, die diese Informationen gibt. Was tatsächlich im RAM des Host-Betriebssystems geschieht, hängt vollständig von der Implementierung der JRE ab.

1
James P.

Wenn Sie in Java ein Objekt aus einer Klasse wie Person p = new Person(); erstellen, ist p tatsächlich eine Adresse eines Speicherorts, der auf einen Typ von Person zeigt.

Wenn Sie ein Statemenet zum Drucken von p verwenden, wird eine Adresse angezeigt. Das Schlüsselwort new erstellt einen neuen Speicherort, der alle Instanzvariablen und -methoden enthält, die in class Person enthalten sind, und p ist die Referenzvariable, die auf diesen Speicherplatz zeigt.

1

dies ist nützlich, um sich mit Hashcode in Java vertraut zu machen:

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

0
himnabil