Operadores relacionales en Java

📅 Actualizado en marzo 2026 ✍️ Ángel López ⏱️ 18 min de lectura ✓ Nivel principiante ★ ★ ★ ★ ★ (5/5)

🔍 ¿Qué son los operadores relacionales?

Los operadores relacionales (también llamados operadores de comparación) son símbolos que permiten comparar dos valores o expresiones entre sí. El resultado de toda operación relacional es siempre un valor de tipo boolean: true si la comparación se cumple, o false si no se cumple.

En la programación diaria con Java, los operadores relacionales son fundamentales porque constituyen la base de toda toma de decisiones. Cada vez que escribimos una sentencia if, un bucle while o una expresión ternaria, estamos usando —directa o indirectamente— uno o más operadores relacionales para determinar qué camino debe seguir el programa.

La estructura general de una expresión relacional es la siguiente:

Pseudocódigo
expresión_1  operador_relacional  expresión_2  →  boolean (true / false)

Por ejemplo, la expresión (3 + 4) > 12 se evalúa como false, ya que 7 no es mayor que 12. En cambio, (3 + 4) < 12 devuelve true.

💡
Concepto clave: A diferencia de lenguajes como C o C++, donde las comparaciones devuelven enteros (0 o 1), en Java los operadores relacionales devuelven exclusivamente valores boolean. No se puede usar un entero como condición en un if: la expresión if (1) genera un error de compilación en Java.

📊 Tabla resumen de operadores relacionales en Java

Java proporciona seis operadores relacionales. Todos ellos son operadores binarios (requieren dos operandos) y devuelven un resultado boolean:

Operador Nombre Ejemplo Resultado Descripción
== Igual a 5 == 5 true Verdadero si ambos operandos tienen el mismo valor
!= Distinto de 5 != 3 true Verdadero si los operandos tienen valores diferentes
> Mayor que 7 > 3 true Verdadero si el operando izquierdo es mayor
< Menor que 3 < 7 true Verdadero si el operando izquierdo es menor
>= Mayor o igual que 5 >= 5 true Verdadero si el operando izquierdo es mayor o igual
<= Menor o igual que 3 <= 7 true Verdadero si el operando izquierdo es menor o igual
Regla mnemotécnica: Los operadores compuestos (>=, <=, !=) siempre llevan el signo = a la derecha, nunca a la izquierda. Escribir => o =< provoca un error de compilación.

⚖️ Operador de igualdad (==)

El operador == devuelve true cuando ambos operandos tienen el mismo valor. Es, junto con !=, el operador relacional más utilizado en Java, ya que interviene en prácticamente toda estructura condicional.

▶️ Igualdad con tipos primitivos

Cuando se comparan tipos primitivos (int, double, char, boolean, etc.), el operador == compara directamente los valores almacenados:

Java
int a = 10;
int b = 10;
int c = 20;

System.out.println(a == b);   // true  → mismo valor
System.out.println(a == c);   // false → valores diferentes
System.out.println(a == 10);  // true  → comparación con literal

double precio = 9.99;
System.out.println(precio == 9.99);  // true

char letra = 'A';
System.out.println(letra == 'A');    // true
System.out.println(letra == 65);     // true → 'A' tiene código Unicode 65

⚠️ Cuidado con la igualdad en punto flotante

Los números en punto flotante (float y double) tienen una precisión limitada, lo que puede producir resultados inesperados al compararlos con ==:

Java
double resultado = 0.1 + 0.2;
System.out.println(resultado);          // 0.30000000000000004
System.out.println(resultado == 0.3);   // false ← ¡sorpresa!

// Solución: comparar con un margen de tolerancia (epsilon)
final double EPSILON = 1e-9;
System.out.println(Math.abs(resultado - 0.3) < EPSILON);  // true
⚠️
Error frecuente: Nunca compares valores double o float directamente con == si proceden de operaciones aritméticas. La representación en coma flotante según el estándar IEEE 754 introduce pequeños errores de redondeo que hacen que comparaciones aparentemente obvias fallen. Usa siempre un valor épsilon.

🔀 Operador de desigualdad (!=)

El operador != es el opuesto lógico de ==: devuelve true cuando los dos operandos no tienen el mismo valor, y false cuando sí lo tienen.

Java
int intentos = 3;
int maxIntentos = 5;

System.out.println(intentos != maxIntentos);  // true  → 3 ≠ 5
System.out.println(intentos != 3);            // false → 3 = 3

boolean activo = true;
System.out.println(activo != false);          // true

// Uso típico en bucles: repetir mientras no se alcance el límite
while (intentos != maxIntentos) {
    System.out.println("Intento " + intentos);
    intentos++;
}
// Salida: Intento 3, Intento 4

En la práctica, != se utiliza con frecuencia para validar que una variable no contenga un valor prohibido, para comprobar que una referencia no sea null, o como condición de continuación en bucles.

💡
Equivalencia lógica: La expresión a != b es lógicamente equivalente a !(a == b). Sin embargo, la forma directa con != es más legible y se considera mejor práctica.

📐 Operadores mayor que (>) y menor que (<)

Estos operadores comparan la magnitud de dos valores numéricos. Devuelven true cuando la relación de orden se cumple, y false en caso contrario.

Java
int edad = 25;

// Mayor que
System.out.println(edad > 18);   // true  → 25 es mayor que 18
System.out.println(edad > 25);   // false → 25 NO es mayor que 25 (es igual)
System.out.println(edad > 30);   // false → 25 no es mayor que 30

// Menor que
System.out.println(edad < 30);   // true  → 25 es menor que 30
System.out.println(edad < 25);   // false → 25 NO es menor que 25 (es igual)
System.out.println(edad < 18);   // false → 25 no es menor que 18

🔹 Comparación de caracteres

En Java, los caracteres (char) se representan internamente como valores numéricos Unicode (UTF-16). Al compararlos con operadores relacionales, se comparan sus códigos numéricos:

Java
// Códigos Unicode relevantes:
// '0'-'9' → 48-57  |  'A'-'Z' → 65-90  |  'a'-'z' → 97-122

char c1 = 'a';   // código 97
char c2 = 'A';   // código 65
char c3 = 'z';   // código 122

System.out.println(c1 > c2);    // true  → 97 > 65
System.out.println(c1 < c3);    // true  → 97 < 122
System.out.println('5' > '2');   // true  → 53 > 50

// Verificar si un carácter es una letra minúscula
char letra = 'm';
boolean esMinuscula = (letra >= 'a' && letra <= 'z');
System.out.println(esMinuscula);  // true
Rango de caracteres Códigos Unicode Ejemplo
Dígitos '0' a '9' 48 – 57 '5' tiene código 53
Mayúsculas 'A' a 'Z' 65 – 90 'M' tiene código 77
Minúsculas 'a' a 'z' 97 – 122 'm' tiene código 109

📏 Operadores mayor o igual (>=) y menor o igual (<=)

Estos operadores son versiones «inclusivas» de > y <. Devuelven true también cuando los operandos son iguales, lo cual los hace especialmente útiles para validar rangos y límites.

Java
int nota = 5;

// Mayor o igual
System.out.println(nota >= 5);    // true  → 5 es igual a 5, se cumple
System.out.println(nota >= 4);    // true  → 5 es mayor que 4
System.out.println(nota >= 6);    // false → 5 no es mayor ni igual que 6

// Menor o igual
System.out.println(nota <= 5);    // true  → 5 es igual a 5, se cumple
System.out.println(nota <= 10);   // true  → 5 es menor que 10
System.out.println(nota <= 4);    // false → 5 no es menor ni igual que 4

// Caso práctico: validar que una nota esté en rango [0, 10]
boolean notaValida = (nota >= 0 && nota <= 10);
System.out.println("¿Nota válida? " + notaValida);  // true

🔹 Diferencia clave entre > y >=

La diferencia parece sutil, pero tiene un impacto directo en la lógica de los programas. Observa este ejemplo donde una pequeña confusión cambia el resultado:

Java
int edad = 18;

// ¿Es mayor de edad? Depende del operador elegido:
if (edad > 18) {
    System.out.println("Mayor de edad");  // NO se imprime (18 no es > 18)
}

if (edad >= 18) {
    System.out.println("Mayor de edad");  // SÍ se imprime (18 es >= 18)
}
Buena práctica: Cuando un valor límite debe incluirse en la condición (por ejemplo, «edad mínima 18 años» significa que 18 ya es válido), usa siempre el operador inclusivo (>= o <=). Una confusión entre > y >= es una de las fuentes de bugs más comunes en programación, conocida como error off-by-one.

🧩 Comparar objetos y Strings: == vs equals()

Esta sección aborda una de las fuentes de errores más frecuentes para quienes comienzan a programar en Java. Cuando se trabaja con objetos (incluidos los String), el operador == se comporta de manera diferente a como lo hace con tipos primitivos.

🔹 El operador == con objetos compara referencias

Con tipos primitivos, == compara valores. Pero con objetos, == compara si las dos variables apuntan al mismo objeto en memoria (la misma referencia), no si sus contenidos son iguales:

Java
// Con String: == puede engañar
String s1 = new String("Hola");
String s2 = new String("Hola");
String s3 = s1;

System.out.println(s1 == s2);       // false → objetos distintos en memoria
System.out.println(s1 == s3);       // true  → misma referencia
System.out.println(s1.equals(s2));  // true  → mismo contenido "Hola"

// Pool de Strings (caso especial)
String s4 = "Hola";
String s5 = "Hola";
System.out.println(s4 == s5);       // true → apuntan al mismo literal del pool
System.out.println(s4 == s1);       // false → s1 se creó con new (fuera del pool)

🔹 La regla de oro para comparar Strings

⚠️
Regla de oro: Para comparar el contenido de dos Strings en Java, usa siempre equals() o equalsIgnoreCase(). Nunca uses == para comparar Strings, aunque parezca funcionar en algunos casos (por el pool de literales), porque fallará con Strings creados dinámicamente (con new, leídos de archivo, recibidos por teclado, etc.).
Java
String usuario = obtenerUsuarioDeBD();  // viene de una fuente externa

// ❌ INCORRECTO — puede fallar impredeciblemente
if (usuario == "admin") { ... }

// ✅ CORRECTO — compara el contenido real
if (usuario.equals("admin")) { ... }

// ✅ MEJOR — evita NullPointerException si usuario es null
if ("admin".equals(usuario)) { ... }

// ✅ Comparación sin distinguir mayúsculas/minúsculas
if ("admin".equalsIgnoreCase(usuario)) { ... }

🔹 Comparar otros objetos: equals() y compareTo()

La misma regla se aplica a cualquier objeto. Los operadores >, <, >=, <= no se pueden usar con objetos (error de compilación). Para establecer un orden entre objetos, Java ofrece dos mecanismos:

Mecanismo Interfaz Método Uso
Orden natural Comparable<T> compareTo(T otro) La clase define su propio criterio de ordenación
Orden externo Comparator<T> compare(T o1, T o2) Se define un criterio de ordenación sin modificar la clase
Java
// String implementa Comparable → se puede usar compareTo()
String nombre1 = "Ana";
String nombre2 = "Carlos";

int comparacion = nombre1.compareTo(nombre2);
// comparacion < 0 → nombre1 va antes que nombre2 (orden alfabético)
// comparacion == 0 → son iguales
// comparacion > 0 → nombre1 va después que nombre2

System.out.println(comparacion);  // negativo → "Ana" < "Carlos"

🔄 Tipos compatibles en comparaciones

No todas las combinaciones de tipos pueden compararse con operadores relacionales. Java establece reglas claras de compatibilidad:

Comparación ¿Permitida? Comportamiento
int con int ✅ Sí Comparación directa de valores
int con double ✅ Sí El int se promueve a double
char con int ✅ Sí El char se promueve a int (valor Unicode)
byte con long ✅ Sí El byte se promueve a long
boolean con int ❌ No Error de compilación
boolean con boolean Solo == y != No se puede usar >, <, >=, <=
String con String Solo == y != Compara referencias (usar equals() para contenido)
Objeto con primitivo ❌ No Error de compilación (excepto autoboxing)

🔹 Promoción automática de tipos (widening)

Cuando se comparan dos tipos numéricos diferentes, Java convierte automáticamente el tipo más pequeño al más grande antes de realizar la comparación. Esta conversión sigue la jerarquía:

Jerarquía de promoción
byte → short → int → long → float → double
          ↑
         char
Java
int entero = 5;
double decimal = 5.0;
char letra = 'A';     // valor Unicode: 65

System.out.println(entero == decimal);  // true  → 5 se promueve a 5.0
System.out.println(letra > 60);         // true  → 65 > 60
System.out.println(letra == 65);        // true  → 'A' se promueve a int 65

// Caso especial con long y float
long valorGrande = 123456789L;
float valorFloat = 123456789.0f;
System.out.println(valorGrande == valorFloat);  // true (¡puede perder precisión!)

🏗️ Precedencia y asociatividad

Los operadores relacionales tienen una posición específica en la jerarquía de precedencia de Java. Conocerla es esencial para evitar errores de lógica en expresiones complejas:

Prioridad Categoría Operadores Asociatividad
1 (más alta) Unarios ++ -- ! + - Derecha → Izquierda
2 Aritméticos multiplicativos * / % Izquierda → Derecha
3 Aritméticos aditivos + - Izquierda → Derecha
4 Relacionales de orden > < >= <= instanceof Izquierda → Derecha
5 Relacionales de igualdad == != Izquierda → Derecha
6 AND lógico && Izquierda → Derecha
7 OR lógico || Izquierda → Derecha
8 (más baja) Asignación = += -= *= /= Derecha → Izquierda
💡
Detalle importante: Observa que los operadores de orden (>, <, >=, <=) tienen mayor precedencia que los de igualdad (==, !=). Esto permite escribir expresiones combinadas sin paréntesis: a > b == c < d se evalúa como (a > b) == (c < d), comparando dos resultados booleanos.
Java
int a = 10, b = 5, c = 3;

// Sin paréntesis: los aritméticos se evalúan primero
boolean resultado = a - b > c;
// Equivale a: (a - b) > c → (10 - 5) > 3 → 5 > 3 → true

// Combinación con lógicos: los relacionales se evalúan antes
boolean complejo = a > b && b > c;
// Equivale a: (a > b) && (b > c) → true && true → true

// Buena práctica: usar paréntesis para mayor claridad
boolean claro = (a > b) && (b > c);  // Misma lógica, más legible
Buena práctica: Aunque Java evalúa las precedencias correctamente, usar paréntesis explícitos en expresiones complejas mejora la legibilidad y reduce errores. El código se lee muchas más veces de las que se escribe.

🎓 Ejemplo completo: sistema de calificaciones

Este ejemplo integra todos los operadores relacionales en un programa completo que simula un sistema de calificaciones universitario. Clasifica alumnos según su nota, aplica reglas de negocio con validaciones y genera un informe:

Java
public class SistemaCalificaciones {

    // Constantes del sistema
    static final double NOTA_MINIMA = 0.0;
    static final double NOTA_MAXIMA = 10.0;
    static final double NOTA_APROBADO = 5.0;
    static final double NOTA_NOTABLE = 7.0;
    static final double NOTA_SOBRESALIENTE = 9.0;
    static final double NOTA_MATRICULA = 9.5;

    public static String clasificar(double nota) {
        // Validación con operadores relacionales
        if (nota < NOTA_MINIMA || nota > NOTA_MAXIMA) {
            return "ERROR: Nota fuera de rango [0-10]";
        }

        // Clasificación usando operadores >= y <
        if (nota >= NOTA_MATRICULA) {
            return "Matrícula de Honor";
        } else if (nota >= NOTA_SOBRESALIENTE) {
            return "Sobresaliente";
        } else if (nota >= NOTA_NOTABLE) {
            return "Notable";
        } else if (nota >= NOTA_APROBADO) {
            return "Aprobado";
        } else {
            return "Suspenso";
        }
    }

    public static void imprimirInforme(String[] nombres, double[] notas) {
        int aprobados = 0;
        int suspensos = 0;
        double mejorNota = NOTA_MINIMA;
        String mejorAlumno = "";

        System.out.println("╔════════════════════════════════════════════╗");
        System.out.println("║       INFORME DE CALIFICACIONES           ║");
        System.out.println("╠════════════════════════════════════════════╣");

        for (int i = 0; i < nombres.length; i++) {
            String calificacion = clasificar(notas[i]);
            System.out.printf("║ %-15s │ %4.1f │ %-20s ║%n",
                              nombres[i], notas[i], calificacion);

            // Contar aprobados y suspensos
            if (notas[i] >= NOTA_APROBADO) {
                aprobados++;
            } else {
                suspensos++;
            }

            // Encontrar la mejor nota
            if (notas[i] > mejorNota) {
                mejorNota = notas[i];
                mejorAlumno = nombres[i];
            }
        }

        // Estadísticas finales
        double porcentajeAprobados = (aprobados * 100.0) / nombres.length;
        System.out.println("╠════════════════════════════════════════════╣");
        System.out.printf("║ Aprobados: %d | Suspensos: %d             ║%n",
                          aprobados, suspensos);
        System.out.printf("║ Tasa aprobados: %.1f%%                    ║%n",
                          porcentajeAprobados);
        System.out.printf("║ Mejor: %s (%.1f)                          ║%n",
                          mejorAlumno, mejorNota);

        // Alerta si la tasa de aprobados es baja
        if (porcentajeAprobados < 50.0) {
            System.out.println("║ ⚠️  ALERTA: tasa de aprobados < 50%     ║");
        }
        System.out.println("╚════════════════════════════════════════════╝");
    }

    public static void main(String[] args) {
        String[] nombres = {"Ana", "Carlos", "Elena", "Pedro", "Lucía"};
        double[] notas   = { 9.7,     4.5,     7.8,     5.0,     9.2 };

        imprimirInforme(nombres, notas);
    }
}

Salida esperada:

Salida
╔════════════════════════════════════════════╗
║       INFORME DE CALIFICACIONES           ║
╠════════════════════════════════════════════╣
║ Ana             │  9.7 │ Matrícula de Honor    ║
║ Carlos          │  4.5 │ Suspenso              ║
║ Elena           │  7.8 │ Notable               ║
║ Pedro           │  5.0 │ Aprobado              ║
║ Lucía           │  9.2 │ Sobresaliente         ║
╠════════════════════════════════════════════╣
║ Aprobados: 4 | Suspensos: 1              ║
║ Tasa aprobados: 80.0%                    ║
║ Mejor: Ana (9.7)                          ║
╚════════════════════════════════════════════╝

🚫 Errores frecuentes

Estos son los errores más comunes al trabajar con operadores relacionales en Java. Conocerlos te ahorrará horas de depuración:

❌ Error 1: Confundir = (asignación) con == (comparación)

Java
int x = 5;

// ❌ ERROR: esto es una asignación, no una comparación
// if (x = 10) { ... }   // Error de compilación en Java

// ✅ CORRECTO: doble igual para comparar
if (x == 10) {
    System.out.println("x vale 10");
}

En Java, este error se detecta en tiempo de compilación (a diferencia de C/C++), porque una asignación devuelve un int, no un boolean, y el if exige un boolean. Sin embargo, con variables boolean, el error pasa desapercibido:

Java
boolean activo = false;

// ❌ BUG SILENCIOSO: asigna true a activo y entra siempre
if (activo = true) {
    System.out.println("Siempre se ejecuta");  // ¡Siempre imprime!
}

// ✅ CORRECTO
if (activo == true) { ... }
// ✅ AÚN MEJOR (idiomático)
if (activo) { ... }

❌ Error 2: Comparar Strings con ==

Java
import java.util.Scanner;

Scanner sc = new Scanner(System.in);
System.out.print("¿Continuar? (si/no): ");
String respuesta = sc.nextLine();

// ❌ Puede fallar: compara referencias, no contenido
if (respuesta == "si") { ... }

// ✅ CORRECTO
if (respuesta.equals("si")) { ... }

// ✅ MEJOR: tolera null y mayúsculas/minúsculas
if ("si".equalsIgnoreCase(respuesta)) { ... }

❌ Error 3: Escribir los operadores compuestos al revés

Java
int nota = 7;

// ❌ ERROR DE COMPILACIÓN: el = va siempre a la derecha
// if (nota => 5) { ... }   // Sintaxis inválida
// if (nota =< 10) { ... }  // Sintaxis inválida

// ✅ CORRECTO
if (nota >= 5) { ... }
if (nota <= 10) { ... }

❌ Error 4: Encadenar operadores como en matemáticas

Java
int nota = 7;

// ❌ ERROR: en Java NO se pueden encadenar comparaciones
// if (0 <= nota <= 10) { ... }  // Error de compilación

// Motivo: Java evalúa de izquierda a derecha:
// (0 <= nota) → true  →  (true <= 10) → Error: boolean vs int

// ✅ CORRECTO: usar operador lógico AND
if (nota >= 0 && nota <= 10) {
    System.out.println("Nota válida");
}

❌ Error 5: Comparar con NaN

Java
double resultado = 0.0 / 0.0;  // NaN (Not a Number)

// ❌ TODAS estas comparaciones devuelven false
System.out.println(resultado == Double.NaN);   // false
System.out.println(resultado > 0);             // false
System.out.println(resultado < 0);             // false
System.out.println(resultado == resultado);    // false ← ¡NaN ≠ NaN!

// ✅ CORRECTO: usar el método isNaN()
System.out.println(Double.isNaN(resultado));   // true

✏️ Ejercicios prácticos

Practica los operadores relacionales con estos ejercicios de dificultad progresiva. Intenta resolverlos antes de consultar la solución.

Ejercicio 1: Clasificador de edades

Escribe un programa que reciba una edad (int) y devuelva la clasificación correspondiente: «Menor de edad» (edad < 18), «Adulto» (18 ≤ edad < 65), «Jubilado» (edad ≥ 65). Si la edad es negativa o superior a 130, debe mostrar «Edad no válida».

Ejercicio 2: Comparador de tres números

Escribe un método que reciba tres números enteros y devuelva el mayor de los tres. Si hay empate entre dos o más valores, devuelve ese valor. Usa solo operadores relacionales y el operador ternario (sin Math.max()).

Ejercicio 3: Validador de contraseña

Escribe un método que valide una contraseña según estas reglas: longitud ≥ 8 caracteres, longitud ≤ 64 caracteres, debe contener al menos una mayúscula, al menos una minúscula y al menos un dígito. El método debe recorrer la cadena carácter a carácter usando operadores relacionales para identificar mayúsculas (c >= 'A' && c <= 'Z'), minúsculas y dígitos.

❓ Preguntas frecuentes sobre Operadores relacionales en Java

Las dudas más comunes respondidas de forma clara y directa.

El operador == compara referencias en objetos (si apuntan a la misma posición de memoria) y valores en tipos primitivos. El método equals() compara el contenido real de los objetos. Para comparar cadenas de texto (String) siempre se debe usar equals(), nunca ==.
Sí. Java realiza una promoción automática (widening) del tipo más pequeño al más grande. Si comparas un int con un double, el int se convierte a double antes de la comparación. Por ejemplo, (5 == 5.0) devuelve true porque 5 se promueve a 5.0.
Todos los operadores relacionales en Java devuelven un valor de tipo boolean: true si la comparación se cumple, o false si no se cumple. Este resultado puede almacenarse en una variable boolean, usarse en una condición if o combinarse con operadores lógicos.
Sí. Los caracteres en Java se representan internamente como valores numéricos Unicode (UTF-16). Al compararlos con operadores relacionales, se comparan sus valores numéricos. Por ejemplo, 'a' > 'A' es true porque el código Unicode de 'a' (97) es mayor que el de 'A' (65).
No. Los operadores >=, <=, > y < solo se pueden usar con tipos primitivos numéricos y char. Para comparar objetos se debe implementar la interfaz Comparable y usar el método compareTo(), o usar un Comparator. Intentar usar estos operadores con objetos produce un error de compilación.
La comparación NaN == NaN devuelve false. Esta es una regla especial del estándar IEEE 754 que Java respeta. NaN no es igual a ningún valor, incluido él mismo. Para verificar si un valor es NaN, se debe usar el método Double.isNaN() o Float.isNaN().
Valora este artículo

💬 Foro de discusión

¿Tienes dudas sobre Operadores relacionales en Java? Comparte tu pregunta con la comunidad.

¿Tienes cuenta? o comenta como invitado ↓

Todavía no hay mensajes. ¡Sé el primero en participar!