Diferencias entre el operador == y el método equals en Java

En Java, el operador == y el método equals se utilizan para comparar objetos, pero con propósitos diferentes. Comprender esta distinción es esencial para escribir código robusto y evitar errores comunes.

Operador ==

El operador == compara las referencias de los objetos en memoria. Para tipos primitivos, verifica si los valores son idénticos. Para tipos de rfeerencia (objetos), determina si dos variables apuntan a la misma instancia en el heap.

Método equals

El método equals define una lógica de igualdad personalizable. Por defecto, en la clase Object, su comportamiento es equivalente al operador ==, comparando referencias. Sin embargo, muchas clases (como String o Integer) sobrescriben este método para compraar el contenido o los atributos de los objetos.

Tipos de datos

En Java, los datos se clasifican en dos categorías:

  • Tipos primitivos: Incluyen byte, short, char, int, long, float, double y boolean. La comparación con == verifica igualdad de valores.
  • Tipos de referencia: Abarcan clases, interfaces y arreglos. La comparación con == examina si las reefrencias apuntan al mismo objeto en memoria.

Considere el siguiente ejemplo con objetos personalizados:

class Ejemplo {
    int id;
    Ejemplo(int id) {
        this.id = id;
    }
}

Ejemplo objA = new Ejemplo(1);
Ejemplo objB = new Ejemplo(1);
Ejemplo objC = objA;

System.out.println(objA == objC);      // true, misma referencia
System.out.println(objA.equals(objC)); // true, por defecto compara referencias
System.out.println(objA == objB);      // false, referencias diferentes
System.out.println(objA.equals(objB)); // false, contenido no comparado por defecto

La salida de este código sería:

true
true
false
false

Implementación de equals en clases

La clase base Object define equals así:

public boolean equals(Object otro) {
    return this == otro;
}

La clase String sobrescribe equals para comparar secuencias de caracteres:

public boolean equals(Object otro) {
    if (this == otro) {
        return true;
    }
    if (!(otro instanceof String)) {
        return false;
    }
    String otraCadena = (String) otro;
    int longitud = this.value.length;
    if (longitud != otraCadena.value.length) {
        return false;
    }
    for (int i = 0; i < longitud; i++) {
        if (this.value[i] != otraCadena.value[i]) {
            return false;
        }
    }
    return true;
}

Caso especial de String y el pool de constantes

En Java, las cadenas literales se almacenan en un pool de constantes. Al crear cadenas con el operador new, se asigna una nueva instancia en el heap. El método intern permite recuperar o agregar una cadena al pool. Ejemplo:

String literal1 = "texto";
String literal2 = "texto";
String nuevaInstancia = new String("texto");
String internada = nuevaInstancia.intern();

System.out.println(literal1 == literal2);        // true, misma referencia en el pool
System.out.println(literal1.equals(literal2));   // true, contenido idéntico
System.out.println(literal1 == nuevaInstancia);   // false, referencias diferentes
System.out.println(literal1.equals(nuevaInstancia)); // true, contenido igual
System.out.println(literal1 == internada);        // true, internada apunta al mismo literal

La salida sería:

true
true
false
true
true

Etiquetas: java operador == equals clase String tipos de datos

Publicado el 6-5 01:51