2012-02-14 16 views
8

Consideremos el siguiente código Java:El comportamiento de los iguales (método) en Java

impresiones declaración
Object a = new Integer(2); 
    Object b = new Integer(2); 
    System.out.println(a.equals(b)); 

    Object x = new Object(); 
    Object y = new Object(); 
    System.out.println(x.equals(y)); 

La primera impresión true y la segunda false.

Si esto es un comportamiento intencional, ¿cómo esto ayuda a programar en Java?

Si esto no es un comportamiento intencionado, ¿es este un defecto en Java?

+2

@downovoter Veo que un votante desfavorecido está en pleno apogeo aquí. ¿Te importaría explicar tus votos? – dasblinkenlight

+0

esto parece duplicado –

Respuesta

23

Voy a responder a su pregunta con reservas, pero debe saber que se está perjudicando a sí mismo si la intención de la pregunta era hacer que aprendiera y su solución era pedir StackOverflow. Eso aparte ...

Este comportamiento es intencional.

El equals() método predeterminado en java.lang.Object compara direcciones de memoria, lo que significa que todos los objetos son diferentes uno de otro (sólo dos referencias al mismo objeto volverá true).

java.lang.Integer anulaciones esto para comparar el valor de los Integer s, por lo que dos diferentes Integer s ambos representan el número dos comparan iguales. Si usó ==, obtendrá false en ambos casos.

práctica estándar en Java es reemplazar el método equals para volver true para objetos que tienen el mismo valor lógico , incluso si se crearon en momentos diferentes (o incluso con diferentes parámetros). No es muy útil tener objetos que representen números si no tienes una manera de preguntar: "¿estas dos cosas representan el mismo valor?".

Dicho sea de paso, y esto es una tangente aquí, Java realmente mantiene un caché de objetos Integer para valores pequeños. Por lo tanto, a veces puede obtener dos objetos Integer donde incluso el operador == devolverá true, a pesar de que los obtiene de dos fuentes diferentes. ¡Incluso puede obtener código que se comporte de manera diferente para enteros más grandes que para pequeños, sin tener que mirar los valores integrales!

+0

+1 gran respuesta. Puedo oler que la intención de la pregunta es aclarar el polimorfismo. –

+0

Mientras tenemos el operador == para verificar la dirección de la memoria eqality, ¿por qué Object define un método para verificar la dirección de la memoria y luego dejar que las subclases como Integer() lo sobrescriban para usarlo de otra manera? – siva636

+0

@MISS_DUKE Porque no puede anular '=='. Y las subclases realmente no hacen que se use "de otra manera": existe la expectativa de que cada clase haga que haga lo mismo * lógico * para esa clase en particular. Este es un principio de herencia: si tienes un método 'makeSound()', para un pato sería "quack", y para una vaca sería "moo", pero en general produce el sonido adecuado para el animal de implementación . – Borealid

6

Este es el comportamiento previsto.

Object.equals() considera la identidad del objeto (es decir, un objeto solo es igual a sí mismo), que es lo único que puede hacer por los objetos genéricos.

Integer reemplaza el método para depender del valor entero, ya que dos objetos enteros con el mismo valor son lógicamente iguales. Muchas otras clases también anulan equals() ya que es un mecanismo básico de la API estándar y muchas funciones, por ejemplo, en el marco de colecciones depende de ello.

¿Por qué estás desconcertado por el comportamiento de todos modos? La mayoría de las personas solo se confunden con el operador ==no comportándose así (funciona como Object.equals()).

2

El método equals en Java sirve a un propósito específico: se determina si los objetos son lógicamente igual, es decir, su contenido es el mismo, sea lo que significa en el contexto de cada clase específica. Esto está en contraste con los objetos que son el mismo: dos objetos diferentes podrían ser lógicamente equivalentes.

Volviendo a su ejemplo, a y b son objetos diferentes que representan la misma entidad lógica - un valor entero de 2. Modelan el mismo concepto: un número entero, y los números enteros con el mismo valor son idénticos entre sí. a y b son, por lo tanto, iguales. Por otro lado, los objetos x y y no representan la misma entidad lógica (de hecho, no representan nada). Es por eso que no son ni lo mismo ni son equivalentes.

+0

@downvoter Por favor explique su voto. – dasblinkenlight

+0

upvoted para equilibrar downvote injusto, no entiendo por qué esta pregunta se desestimó en el primer lugar –

0

Es intencional, por supuesto.

Al comparar Integer objetos, equals devuelve true si sus valores (en su caso, 1) son iguales.

Aplicado en diferentes objetos del tipo Object, devuelve false.

x.equals(x) 

devolvería true.

0

Véase también Object.equals() doc. Por cierto, considere usar Integer.valueOf(2) en lugar de new Integer(2), ya que reduce la huella de memoria.

Una última cosa divertida Integer.valueOf(2)==Integer.valueOf(2) volverá cierto, pero Integer.valueOf(2000)==Integer.valueOf(2000) volverá falso, porque en el primer caso, recibirá el doble de la misma instancia del objeto Integer (hay un caché detrás) pero no en el segundo caso porque la caché es solo para valores comprendidos entre -127 y 128

+0

Su respuesta no está realmente relacionada con la pregunta.El resultado de == es normal, no gracioso. El operador == compara la referencia que no tiene nada que ver con el valor. Por eso debemos usar los métodos equals o compareTo al trabajar con Numbers. –

+1

Bueno, esto es discutible. Pero obviamente él no sabía exactamente el propósito del método de igualdad. Por lo general, se confunde con '==' y como estábamos hablando de enteros, pensé que podría ser relevante saber que existen comportamientos extraños y que a veces == arrojará el mismo resultado que igual y otras veces no. –

Cuestiones relacionadas