10 errores tontos que todo programador en Java sigue cometiendo

“La experiencia es ese maravilloso don que te llega justo después de haber metido la pata.” — Alguien que programó sin tests

Dicen que con el tiempo uno se vuelve mejor programador. Que la experiencia ayuda a evitar los errores de principiante. Y es verdad… en parte. Porque hay ciertos fallos que, por algún motivo misterioso, siguen apareciendo incluso entre desarrolladores con años de práctica en Java.

No hablamos de patrones complicados ni de problemas de concurrencia en microservicios. Hablamos de esos errores básicos, casi entrañables, que uno esperaría dejar atrás… pero no. Aquí va un repaso a 10 meteduras de pata que se siguen viendo —en proyectos reales, en producción, en 2025— por parte de programadores veteranos (ninguno de los cuales eres tú, claro).

1. No inicializar una variable antes de usarla

Java te da pistas, pero a veces no suficientes. Atributos que empiezan como null y luego explotan a media ejecución.

private Cliente cliente;

public void procesar() {
    cliente.getNombre(); // ¡Boom!
}

Solución:
Inicializa bien, usa constructores o revisa si Optional puede salvarte el pellejo.

2. Comparar cadenas con ==

Sí, otra vez. Sabemos que hay que usar .equals(), pero en algún rincón oscuro del código siempre aparece un == traicionero.

if (usuario.getRol() == "admin") { ... } // NO

Solución:
Siempre «admin».equals(rol) o te espera un bug tan invisible como molesto.

3. Olvidar el break en un switch

El clásico. Un switch sin break es como una parrillada sin cerveza: todo se mezcla y no sabes cómo terminó.

switch (opcion) {
    case 1: hacerEsto();
    case 2: hacerAquello(); // ¿Por qué se ejecutan los dos?
}

Solución:
¡Pon el break! Y si usas switch moderno con flechitas (->), aún mejor.

4. Atraparlo todo con un catch (Exception e)

Capturar todas las excepciones “por si acaso” es como usar una red de pescar para cazar moscas.

try {
    algoPeligroso();
} catch (Exception e) {
    // Nunca hagas esto
    e.printStackTrace();
}

Solución:
Captura lo que realmente esperas. El resto, déjalo que grite.

5. No cerrar recursos correctamente

Un FileReader, una conexión a base de datos, un Scanner… y ninguno con .close().

Solución:
try-with-resources. Más limpio, más seguro, más feliz.

6. Abusar de los static

Hay quien convierte todos sus métodos en static para “ahorrarse instancias” o “acceder más fácil desde cualquier parte”. ¿El resultado? Código que parece más bien un script gigante disfrazado de Java.

public class Utilidades {
    public static void validarUsuario(...) { ... }
    public static void enviarCorreo(...) { ... }
    public static void guardarEnBaseDeDatos(...) { ... }
}

Solución:
Usa static solo para funciones puramente auxiliares, que no dependan de estado ni de contexto, el mítico StringUtils.

7. Olvidar comprobar null porque nunca llegará null

Kotlin no te dejaría hacerlo. Java, en cambio, te deja morir con elegancia:

usuario.getDirección().getCiudad().equals("Madrid");

Solución:
Divide la lógica, comprueba intermedios o introduce Optional si tienes fe.

8. Escribir clases gigantescas que hacen de todo

Una clase que valida, calcula, persiste, notifica, cocina y pasea al perro.

public class GestorUniversal {
    // 2000 líneas de código sin modularizar
}

Solución:
Divide y vencerás. SRP (Single Responsibility Principle).

9. Ignorar las advertencias del compilador

“Warning: método foo() está obsoleto.” — Tú lo ignoras.
“Warning: unchecked conversion.” — Lo ignoras también.

Hasta que un día… BOOM.

Solución:
Trata los warnings como errores suaves. Si el compilador se queja, no es por gusto.

10. Creer que los tests son opcionales

«Solo es una clase sencilla, no necesita test.»
Spoiler: sí los necesita. Y te vas a arrepentir justo el día que algo falle… y no sepas dónde.

Solución:
Testea lo importante. Usa JUnit, incluso para clases “tontas”. Si no tienes tiempo para tests, vas a necesitar más tiempo para los bugs.