En la programación Java tradicional, ya no necesitará tratar con objetos o ubicaciones de Java desde la memoria. Cuando hablas de esto en foros, la primera pregunta que surge es ¿por qué necesitas saber la dirección de un objeto Java? Es una pregunta válida. Pero en el pasado nos reservamos el derecho de realizar ensayos. No hay nada de malo en explorar cuestiones en territorio inexplorado. Se me ocurrió un experimento utilizando paquetes de la empresa Sun. Unsafe es un paquete que pertenece a sun.misc. Tal vez este paquete le resulte un poco desconocido, eche un vistazo al código fuente y los métodos y sabrá a qué me refiero.
La gestión de seguridad de Java proporciona suficiente ocultación para garantizar que no puedas alterar la memoria tan fácilmente. Como primer paso, pensé en obtener la ubicación de memoria de un objeto Java. Hasta que comencé a explorar, estaba 100% seguro de que era imposible encontrar la ubicación de la dirección de un objeto en Java.
La documentación de la API Unsafe.java de Sun muestra que tenemos acceso a la dirección utilizando el método objectFieldOffset. Este método parece decir: "La clase en el informe asigna su ubicación en un área de almacenamiento específica". También dice: "Este es solo un acceso donde la cookie se pasa a una memoria de montón insegura". De todos modos, puedo asignar la ubicación de memoria donde se almacena un objeto desde el almacenamiento de su clase. Se podría argumentar que lo que obtenemos no es la dirección de memoria física absoluta de un objeto. Sin embargo, obtuvimos la dirección de la memoria lógica. ¡El siguiente programa será de gran interés para ti!
Como primer paso, tengo que conseguir un objeto de la clase Unsafe. Esto es difícil porque los constructores son privados. Existe un método llamado getUnsafe que devuelve un objeto inseguro. La gestión de seguridad de Java requiere que usted otorgue privilegios de código fuente. Utilicé un poco de reflexión y obtuve una instancia. Sé que hay mejores formas de obtener una instancia, pero elegí el siguiente método para evitar la administración de seguridad.
Para utilizar objetos inseguros, simplemente llame a objectFieldOffset y staticFieldOffset. El resultado es la dirección de asignación de memoria de la clase.
El siguiente programa de ejemplo se puede ejecutar en JDK1.6.
clase pública Ubicación del objeto {
manzana int estática privada = 10;
privado int naranja = 10;
public static void main (String [] args) lanza una excepción {
Inseguro inseguro = getUnsafeInstance();
Campo appleField = ObjectLocation.class.getDeclaredField("manzana");
System.out.println("Ubicación de Apple: "
+ inseguro.staticFieldOffset(appleField));
Campo orangeField = ObjectLocation.class.getDeclaredField("orange");
System.out.println("Ubicación de Orange: "
+ inseguro.objectFieldOffset(orangeField));
}
getUnsafeInstance() estático privado inseguro lanza SecurityException,
NoSuchFieldException, IllegalArgumentException,
Excepción de acceso ilegal {
Campo theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(verdadero);
return (Inseguro) theUnsafeInstance.get(Unsafe.class);
}
}