Java: Identidad vs Igualdad


En cualquier lenguaje que permita manejar punteros vamos a encontrarnos con un asunto no muy complicado pero con el que los novatos podemos liarnos un poco al principio. Se trata de distinguir los conceptos de identidad e igualdad.

Vamos a aclarar la diferencia mediante un sencillo programa de ejemplo. Voy a crear una clase llamada Contact que almacene el nombre, apellidos, teléfono e e-mail de cada instancia como Strings. Por simplicidad, solo he escrito un método constructor. Por ahora, no te preocupes del método equals que aparece más abajo.

En mi clase pública voy a escribir el método main. En él, creo un objeto c1 con unos datos de ejemplo. Ahora empieza lo bueno. Si hago la siguiente asignación:
Contact c2=c1;
Estaré creando un puntero c2 que apunta al mismo objeto al que también apunta c1. Cualquier cambio que hiciese en uno de los punteros, lo podría ver también a través del otro. Es decir, que son punteros identicos y la comparación con el operador == devolverá TRUE y en pantalla escribirá:
==

Es fácil intuir que, por el contrario, si ahora asigno al puntero c2 un objeto nuevo, esta comparación nos devolverá FALSE aunque ambos objetos contengan los mismos datos; porque ya son dos objetos independientes. Por eso, el programa escribe que el segundo resultado es:
!=
¿Que sucede? Que son iguales, pero no son idénticos. Son iguales en el sentido de que sus atributos contienen la misma información; pero no son idénticos pues no son el mismo objeto y podemos cambiar uno sin alterar el otro.

Esto nos puede llevar a pensar en un método que compare los atributos de ambos y nos diga si, aun siendo objetos distintos, son equivalentes. Esto es precisamente lo que nos brinda el método equals. Es un método ya predefinido en la clase Object, así que todas las clases (incluso las que tú escribas) lo llevan incorporado. Eso sí, habrá que reescribirlo (con la cláusula @Override) para que se adapte a nuestro caso particular.
En este programa, basta con comprobar si los atributos de la instancia dada son iguales a los del objeto que recibimos como parámetro; y como los atributos también son objetos (Strings), podemos utilizar equals sobre ellos. Si fuesen tipos de datos primitivos (como por ejemplo int), utilizaríamos el operador ==.
En el programa principal se realiza de nuevo la comparación de c1 y c2 mediante el método equals y el resultado ha de ser también TRUE.

Las clases inmutables
En Java se pueden definir clases de objetos como inmutables. Es decir, objetos sobre los que no se pueden realizar cambios; y que si necesitamos alterar, generaran un objeto nuevo que refleje sus nuevos atributos.
Por ejemplo, si yo tengo el String a que contiene la palabra “hola” y quiero añadir una exclamación al final, puedo hacer:
a+"!";
Pero esto me devuelve un objeto diferente, por lo que la forma correcta es:
String b=a+"!"

Si lo piensas, se pueden dar las siguientes situaciones:
1. a y b apuntan al mismo objeto: == y equals
2. a y b apuntan a dos objetos distintos que contienen lo mismo: != y equals
3. a y b apuntan a dos objetos distintos que contienen cosas distintas: != y !equals

Sin embargo, como ya sabemos que String es inmutable, el lenguaje es suficientemente inteligente como para que el operador == y el método equals arrojen siempre el mismo resultado.

Aquí puedes ver todo lo que imprime el programa en su ejecución:

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s