2009-12-25 28 views
102

Mire la imagen siguiente. Cuando creamos un objeto en java con palabra clave nueva, obtenemos una dirección de memoria del sistema operativo.Dirección de memoria de las variables en Java

Cuando escribimos out.println(objName) podemos ver una cadena "especial" como salida. Mis preguntas son:

  1. ¿Qué es esta salida?
  2. Si se trata de dirección de memoria que da por el sistema operativo para nosotros:

    a) ¿Cómo puedo convertir esta cadena a binario?

    b) ¿Cómo se puede obtener la dirección de las variables de un entero?

alt text

+1

bien no estoy votando abajo porque la cuestión es lo suficientemente claro, sólo una sugerencia que debería haber hecho en el texto por lo la gente puede buscarlo – phunehehe

+0

Edité la pregunta. – uzay95

+0

Se ve bien ahora que está editado –

Respuesta

123

Ese es el nombre de la clase y System.identityHashCode() separados por el carácter '@'. Lo que representa el código hash de identidad es específico de la implementación. A menudo es la dirección de memoria inicial del objeto, pero la máquina virtual puede mover el objeto en memoria a lo largo del tiempo. Entonces (brevemente) no puedes confiar en que sea nada.

conseguir las direcciones de memoria de variables no tiene sentido dentro de Java, ya que la JVM está en libertad de poner en práctica los objetos y moverlos como parece ajuste (los objetos pueden/serán moverse durante la recolección de basura, etc.)

Integer.toBinaryString() le dará un número entero en forma binaria.

+0

A @ ....... ¿Qué muestran A y @? – uzay95

+0

Véase más arriba (respuesta editada) –

+28

Otro punto interesante es que * los códigos de hash de identidad * no se garantiza que sean únicos. Por ejemplo, en JVM de 64 bits hay 2^32 códigos hash identidad * pero 2 * 64 * direcciones de memoria *. –

11

Esa es la salida de "toString) (" Objeto de aplicación. Si su clase anula toString(), imprimirá algo completamente diferente.

1

lo que está recibiendo es el resultado del método toString() de la clase de objeto o, más precisamente, el identityHashCode() como uzay95 ha señalado.

"Cuando creamos un objeto en java con la nueva palabra clave, que están recibiendo una dirección de memoria del sistema operativo."

Es importante darse cuenta de que todo lo que haces en Java está a cargo de la máquina virtual de Java. Es la JVM la que está dando esta información. Lo que sucede realmente en la memoria RAM del sistema operativo host depende completamente de la implementación del JRE.

5

Esto es no dirección de memoria Esto es classname @ código hash

donde

classname = nombre completo calificado o nombre absoluto (es decir, el nombre del paquete seguido por nombre de la clase)

código hash = formato hexadecimal (System.identityHashCode (obj) u obj.hashCode() le dará el código hash en formato decimal)

19

Es posible utilizar sun.misc.Unsafe: ver esta gran respuesta de @Peter Lawrey ->Is there a way to get a reference address?

A través de su código para 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(); 
} 

he definido esta prueba:

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

Aquí está la salida:

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

Conclusión:

  • código hash = dirección de
  • toString = clase @ HEX (código hash)
0

En Java cuando está haciendo un obj ect de una clase como Person p = new Person();, p es en realidad una dirección de una ubicación de memoria que apunta a un tipo de Person.

Cuando use un statemenet para imprimir p, verá una dirección. La palabra clave new hace que una nueva ubicación de memoria que contenga todas las variables y métodos de instancia que se incluyen en class Person y p es la variable de referencia que apunta a esa ubicación de memoria.

+0

en su imagen a1 y a2 son dos direcciones de memoria diferentes. Esa es la razón detrás de obtener dos valores diferentes. –

0

Como dijo Sunil, esto no es dirección de memoria .Esta es sólo el código hash

Para obtener el mismo contenido @, puede:

Si hashCode no se reemplaza en esa clase:

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

Si se anula hashCode, se obtiene el valor original con:

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

Esto a menudo se confunde con la dirección de memoria porque si no anula hashCode(), la dirección de memoria se usa para calcular el hash.

-1

toString() es una función de la biblioteca java.lang.Object, que devuelve una representación de cadena de referencia a objeto el cuerpo de toString() es como sigue

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

aquí dirección viene dada por no JVM OS

puede anular la función toString(), proporcionando a su propia aplicación en el cuerpo de la función

Cuestiones relacionadas