Introducción: ¿Por qué los principiantes en Java suelen equivocarse?
Java es uno de los lenguajes de programación más populares y demandados del mundo. Sin embargo, su tipado estricto, la abundancia de código boilerplate y las particularidades de la gestión de memoria a menudo confunden a los desarrolladores novatos. Incluso los programadores experimentados cometen errores clásicos de vez en cuando, pero para los principiantes pueden ser la causa de largas horas de depuración.
En este artículo analizaremos los 10 errores más comunes de los desarrolladores principiantes en Java. Aprenderás a reconocerlos, corregirlos y, lo que es más importante, a no cometerlos en el futuro. Cada punto va acompañado de un ejemplo de código claro y un consejo práctico.
1. Olvidar el NullPointerException (NPE)
El error más conocido y traicionero en Java. La mayoría de las veces, un NPE ocurre cuando intentas llamar a un método o acceder a un campo de un objeto que es null.
Ejemplo del error
public class Main {
public static void main(String[] args) {
String text = null;
int length = text.length(); // NullPointerException!
}
}
Cómo corregirlo
- Siempre verifica si los objetos son
nullantes de usarlos. - Usa
Optionalpara métodos que puedan devolver un valor vacío. - Aplica las anotaciones
@Nullabley@NonNullpara documentar el código.
public static int getLengthSafely(String text) {
return Optional.ofNullable(text)
.map(String::length)
.orElse(0);
}
2. Comparar cadenas con == en lugar de equals()
El operador == compara referencias de objetos, no su contenido. Para las cadenas esto es crítico, ya que Java usa un pool de cadenas y crea nuevos objetos al llamar a new String().
Ejemplo del error
String a = "Hello";
String b = new String("Hello");
System.out.println(a == b); // false! Aunque las cadenas son iguales
Cómo corregirlo
- Siempre usa
equals()para comparar el contenido de las cadenas. - Para ignorar mayúsculas/minúsculas, usa
equalsIgnoreCase().
System.out.println(a.equals(b)); // true
3. Ignorar los recursos: no cerrar Connection, File o Stream
Trabajar con archivos, bases de datos o conexiones de red requiere cerrar explícitamente los recursos. Si no se hace, se producen fugas de memoria y bloqueo de archivos.
Ejemplo del error
FileInputStream fis = new FileInputStream("file.txt");
// Trabajamos con el archivo
// Olvidamos llamar a fis.close();
Cómo corregirlo
A partir de Java 7, usa la construcción try-with-resources. Los recursos se cerrarán automáticamente, incluso si se produce una excepción.
try (FileInputStream fis = new FileInputStream("file.txt")) {
// Trabajamos con el archivo
} catch (IOException e) {
e.printStackTrace();
}
4. No comprender los principios de funcionamiento de equals() y hashCode()
Si sobrescribes equals(), debes sobrescribir también hashCode(). De lo contrario, tus objetos no podrán funcionar correctamente en colecciones como HashSet, HashMap y similares.
Ejemplo del error
class User {
String name;
User(String name) { this.name = name; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(name, user.name);
}
// ¡hashCode no está sobrescrito!
}
Set<User> users = new HashSet<>();
users.add(new User("Alice"));
users.add(new User("Alice"));
System.out.println(users.size()); // 2, aunque se esperaba 1