vulnerability example array java object hashcode

example - object tostring java



¿Cómo se obtiene la "referencia de objeto" de un objeto en Java cuando toString() y hashCode() han sido anulados? (6)

¿Qué es exactamente lo que planeas hacer con él (lo que quieres hacer hace una diferencia con lo que tendrá que llamar).

hashCode , como se define en los JavaDocs, dice:

Tanto como sea razonablemente práctico, el método hashCode definido por el objeto de clase devuelve enteros distintos para objetos distintos. (Esto se implementa típicamente al convertir la dirección interna del objeto en un entero, pero esta técnica de implementación no es requerida por el lenguaje de programación Java ™).

Entonces, si está utilizando hashCode() para averiguar si es un objeto único en la memoria, esa no es una buena manera de hacerlo.

System.identityHashCode hace lo siguiente:

Devuelve el mismo código hash para el objeto dado como lo devolvería el método predeterminado hashCode (), independientemente de si la clase del objeto dado anula hashCode (). El código hash para la referencia nula es cero.

Lo cual, por lo que estás haciendo, suena como lo que quieres ... pero lo que quieres hacer podría no ser seguro dependiendo de cómo se implemente la biblioteca.

Me gustaría imprimir la "referencia de objeto" de un objeto en Java para fines de depuración. Es decir, para asegurarse de que el objeto sea el mismo (o diferente) según la situación.

El problema es que la clase en cuestión hereda de otra clase, que ha anulado tanto a String () como a hashCode (), que normalmente me daría el id.

Situación de ejemplo: ejecutar una aplicación de subprocesos múltiples, donde I (durante el desarrollo) desea comprobar si todos los subprocesos usan o no la misma instancia de un objeto de recurso.


Agregue una identificación única a todas sus instancias, es decir,

public interface Idable { int id(); } public class IdGenerator { private static int id = 0; public static synchronized int generate() { return id++; } } public abstract class AbstractSomething implements Idable { private int id; public AbstractSomething () { this.id = IdGenerator.generate(); } public int id() { return id; } }

Extiende desde AbstractSomething y consulta esta propiedad. Estará a salvo dentro de una única vm (suponiendo que no se juegue con los cargadores de clases para evitar la estática).


Así es como lo resolví:

Integer.toHexString(System.identityHashCode(object));


Double equals == siempre verificará en función de la identidad del objeto, independientemente de la implementación de los objetos de hashCode o equals. Por supuesto, asegúrese de que las referencias a objetos que está comparando sean volatile (en una JVM 1.5+).

Si realmente debe tener el resultado original Object toString (aunque no es la mejor solución para su ejemplo de caso de uso), la biblioteca Commons Lang tiene un método ObjectUtils.identityToString(Object) que hará lo que desee. Desde JavaDoc:

public static java.lang.String identityToString(java.lang.Object object)

Obtiene toString que sería producido por Object si una clase no reemplaza a String en sí. null devolverá nulo.

ObjectUtils.identityToString(null) = null ObjectUtils.identityToString("") = "java.lang.String@1e23" ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"


No puede hacer lo que quiera de forma segura, ya que es posible que el hashCode () predeterminado no devuelva la dirección, y se ha mencionado que son posibles múltiples objetos con el mismo hashCode. La única forma de lograr lo que desea es anular el método hashCode () para los objetos en cuestión y garantizar que todos proporcionen valores únicos. Si esto es factible en su situación es otra cuestión.

Para el registro, he experimentado múltiples objetos con el mismo hashcode predeterminado en una VM de IBM que se ejecuta en un servidor WAS. Tuvimos un defecto por el que los objetos colocados en un caché remoto se sobrescribían. Eso fue una revelación para mí en ese momento ya que asumí que el código hash predeterminado también era la dirección de memoria de los objetos.


simplemente podemos copiar el código de tostring de la clase de objeto para obtener la referencia de la cadena

class Test { public static void main(String args[]) { String a="nikhil"; // it stores in String constant pool String s=new String("nikhil"); //with new stores in heap System.out.println(Integer.toHexString(System.identityHashCode(a))); System.out.println(Integer.toHexString(System.identityHashCode(s))); } }