2012-06-16 13 views
5

Sé que cuando estamos pasando objetos pasamos su referencia como un valor. Pero este valor que obtiene es utilizar el método hashcode() a la derecha (según mis pruebas, es el mismo). Dado que hashcode() no es la dirección de la memoria y no se garantiza que obtenga valores únicos todo el tiempo, ¿pueden ocurrir cosas extrañas como colisiones al pasar objetos?¿qué pasa realmente al pasar objetos en java?

(Suponiendo que no haya hashcode() ser anulado, es decir, devuelve el mismo valor que System.identityHashCode())

Tres son muchas como esta pregunta, pero no puedo encontrar un recurso relevante, que propone una discusión sobre lo que es ser ese valor aprobado y ¿cómo lo obtienes?

EDITAR: Aquí está mi prueba. El valor predeterminado toSting() usa el hashCode() en el interior y lo convierte en un valor hexadecimal. Entonces, cuando estamos pasando objetos, ¿este es el valor que se pasa? ¿O qué hace Java para realizar un seguimiento de todos los objetos (que se pasan) por lo que no habrá ninguna colisión de referencia ?

Object o = new Object(); 
System.out.println(o); 
System.out.println(o.toString()); //both prints same thing - [email protected] 

Respuesta

6

hashcode() no está involucrado de ninguna manera con el almacenamiento de memoria interna de Java. Es solo un método que se supone que devuelve un valor único que puede representar un objeto.

Ahora, sucede que una buena manera de obtener un valor único para representar un objeto es utilizar su dirección de memoria interna. Y eso es lo que hace la implementación predeterminada de hashcode(). Pero el hecho de que hashcode() utiliza una dirección de memoria hace no quiere decir quehashcode() define la dirección de memoria.

+0

Como dices si la implementación predeterminada devuelve la dirección de la memoria, entonces no hay problema. Pero lo que he visto es que no está garantizado (función predeterminada) devolver la dirección de la memoria. Pero, de nuevo, ¿qué ocurre cuando hay más objetos que 2^32 y hashcode() devuelve un número entero de 32 bits? – KillBill

+0

@ user601L 'hashcode()' no es un método infalible. Ocasionalmente hay colisiones. Pero siempre encontrará algún valor que devolverle, independientemente de si usa o no su dirección de memoria para obtenerlo. Realmente no deberías preocuparte demasiado, solo debes saber que las colisiones son posibles en los casos extremos. –

+0

@bohemian Gracias por corregir mi gramática. Soy un idiota. –

2

Pero este valor que se obtiene está utilizando el código hash() método correcto (según mis pruebas es la misma)?

No.

De JSL:

Los valores de referencia (a menudo apenas referencias) son punteros a estas objetos, y una referencia nula especial, que se refiere a ningún objeto.

Leer esta página de Harnessing Java

2

La implementación predeterminada de código hash para Object en Java se basa en la dirección de memoria del objeto, que es también lo que es la referencia.

Esto no significa que se llama a hashCode() para obtener la referencia. Esto no es lo que sucede La variable de referencia simplemente contiene la dirección de la memoria después de obtenerla de una creación de instancias (new Whatever()). De hecho, es común que las implementaciones de clase anulen el hashcode() para hacer algo diferente.

+7

La implementación predeterminada no devuelve la dirección de memoria. Las máquinas virtuales de Java mueven objetos de forma rutinaria durante la fase [compacta] (http://en.wikipedia.org/wiki/Mark-compact_algorithm) de la recolección de elementos no utilizados, por lo que usar la dirección de memoria haría que 'System.identityHashCode' sea inestable. –

1

En JavaObjects se pasan por referencia significa que cada vez que pasa un Object en realidad pasa la referencia del objeto original. Un hashcode depende de los valores de los campos asociados a ese objeto. hashcode no tiene nada que ver con real memory address. es muy raro que dos objetos con los mismos valores tengan hashcode diferente. Incluso si crea dos objetos diferentes pero tienen los mismos valores, su código hash será el mismo siempre depende de cuánto su función hash sea eficiente

+0

Estoy hablando del código hash predeterminado() aquí, o del sistema.identityhashcode(). – KillBill

2

No hay ningún requisito o expectativa de que ese hashCode() sea único. Es no un método de identidad.

Sin embargo, gran parte del JDK espera que si a.equals(b), entonces a.hashCode() == b.hashCode().

Lo contrario nunca se espera; es decir, si !a.equals(b) es no se requiere que a.hashCode() != b.hashCode(). Sin embargo, el rendimiento sufrirá si esto no es generalmente el caso. En otras palabras, se espera que hashCode() tenga pocas colisiones.

La implementación predeterminada hashCode() en la clase Object utiliza normalmente la dirección de memoria para generar la hashCode(), pero no la dirección de retorno, ni hay ningún requisito en la especificación de lenguaje para hacer esto.

Cuestiones relacionadas