2009-12-25 22 views
102

Si prega di guardare l'immagine qui sotto. Quando creiamo un oggetto in java con una nuova parola chiave, riceviamo un indirizzo di memoria dal sistema operativo.Indirizzo di memoria delle variabili in Java

Quando scriviamo out.println(objName) possiamo vedere una stringa "speciale" come output. Le mie domande sono:

  1. Che cos'è questa uscita?
  2. Se si tratta di indirizzo di memoria, che data da OS a noi:

    a) Come posso convertire questa stringa al binario?

    b) Come posso ottenere un indirizzo di variabili intero?

alt text

+1

bene non sto votando giù perché la questione è abbastanza chiaro, solo un suggerimento che si dovrebbe aver fatto in testo in modo le persone possono cercarlo – phunehehe

+0

Ho modificato la domanda. – uzay95

+0

Sembra buono ora è modificato –

risposta

123

Questo è il nome della classe e System.identityHashCode() separati dal carattere '@'. Ciò che rappresenta il codice hash dell'identità è specifico dell'implementazione. Spesso è l'indirizzo di memoria iniziale dell'oggetto, ma l'oggetto può essere spostato in memoria dalla VM nel tempo. Quindi (brevemente) non puoi fare affidamento sul fatto che sia qualcosa.

ottenere gli indirizzi di memoria delle variabili non ha senso all'interno di Java, in quanto la JVM è libero di implementare gli oggetti e spostarli come sembra in forma (gli oggetti possono/si muoveranno intorno durante la raccolta dei rifiuti, ecc)

Integer.toBinaryString() ti darà un numero intero in forma binaria.

+0

A @ ....... Cosa fanno A e @ show? – uzay95

+0

Vedi sopra (risposta modificata) –

+28

Un altro punto interessante è che * i codici hash dell'identità * non sono garantiti come unici. Ad esempio, sulla JVM a 64 bit ci sono 2^32 codici identificativi * di hash * ma 2^64 * indirizzi di memoria *. –

11

Questo è l'output dell'implementazione "toString()" di Object. Se la tua classe sovrascrive toString(), stamperà qualcosa di completamente diverso.

1

Cosa hai trovato è il risultato del metodo toString() della classe Object o, più precisamente, l'identityHashCode() come uzay95 ha sottolineato.

"Quando creiamo un oggetto in Java con la nuova parola chiave, stiamo ottenendo un indirizzo di memoria dal sistema operativo."

È importante rendersi conto che tutto ciò che si fa in Java viene gestito dalla Java Virtual Machine. È la JVM a dare queste informazioni. Ciò che effettivamente accade nella RAM del sistema operativo host dipende interamente dall'implementazione di JRE.

5

Questo è non indirizzo di memoria Questo è nomeclasse @ hashcode

dove

classname = nome completo qualificato o il nome assoluto (ad esempio nome pacchetto seguito dal nome della classe)

hashcode = formato esadecimale (System.identityHashCode (obj) o obj.hashCode() vi darà HashCode in formato decimale)

19

E 'possibile utilizzare sun.misc.Unsafe: vedere questo grande risposta da @Peter Lawrey ->Is there a way to get a reference address?

Utilizzando il suo codice per 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(); 
} 

ho creato questo test:

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

Ecco l'output:

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

Conclusione:

  • codice hash = indirizzo
  • toString = classe @ HEX (codice hash)
0

In Java, quando si stanno facendo un obj ect da una classe come Person p = new Person();, p è in realtà un indirizzo di una posizione di memoria che punta a un tipo di Person.

Quando si utilizza un set di dati per stampare p, verrà visualizzato un indirizzo. La parola chiave new crea una nuova posizione di memoria contenente tutte le variabili di istanza e i metodi inclusi in class Person e p è la variabile di riferimento che punta a tale posizione di memoria.

+0

nella tua immagine a1 e a2 sono due indirizzi di memoria diversi. Questo è il motivo alla base di ottenere due valori diversi. –

0

Come Sunil detto, questo non è indirizzo di memoria .Questo è solo il codice hash

Per ottenere lo stesso contenuto @, è possibile:

Se hashCode non viene sovrascritta in quella classe:

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

Se hashCode viene sovrascritto, si ottiene il valore originale con:

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

Questo è spesso confuso con l'indirizzo di memoria perché se non si esegue l'override di hashCode(), l'indirizzo di memoria viene utilizzato per calcolare l'hash.

-1

toString() è una funzione nella libreria java.lang.Object, che restituisce rappresentazione String riferimento Oggetto del corpo di toString() è il seguente

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

qui indirizzo è dato dalla non JVM OS

è possibile ignorare la funzione toString() fornendo la propria implementazione nel corpo della funzione

Problemi correlati