Qu'est-ce qu'une NullPointerException et comment la corriger ?
La NullPointerException (souvent abrégée NPE) est la star des erreurs Java. Elle survient dès que votre code tente d'utiliser une référence qui pointe sur null comme si elle pointait sur un objet réel.
Le déclencheur le plus simple
String nom = null;
int longueur = nom.length(); // ❌ NullPointerException
nom ne pointe vers aucun objet : appeler length() dessus est impossible. La JVM lève immédiatement une exception.
Les cinq causes les plus courantes
- Variable non initialisée : un champ d'objet vaut
nullpar défaut si vous oubliez de l'initialiser. - Retour de méthode
null: une méthode commeMap.get()renvoienullsi la clé n'existe pas. - Chaînage d'appels (null-chain) :
user.getAddress().getCity()plante sigetAddress()retournenull. - Tableau / collection non initialisé :
List<String> l;sansnew ArrayList<>(). - Auto-unboxing :
int i = integerQuiEstNull;lève NPE lors de la conversion.
Helpful NPE (Java 14+)
Avant Java 14, le message était vague :
Exception in thread "main" java.lang.NullPointerException
at com.example.Main.process(Main.java:15)
Depuis Java 14, le message indique précisément quel accès est null :
Exception in thread "main" java.lang.NullPointerException:
Cannot invoke "String.length()" because "user.address.city" is null
at com.example.Main.process(Main.java:15)
Fonctionnalité activée par défaut à partir de Java 15.
Comment éviter les NPE
1. Vérifier avant d'utiliser
if (nom != null) {
System.out.println(nom.length());
}
2. Inverser les comparaisons avec une constante
if (nom.equals("Alice")) { ... } // ❌ NPE si nom == null
if ("Alice".equals(nom)) { ... } // ✅ sûr
if (Objects.equals(nom, "Alice")) { ... } // ✅ sûr aussi
3. Utiliser Optional pour les retours
public Optional<User> findById(long id) { ... }
findById(42)
.map(User::getEmail)
.ifPresent(System.out::println);
Le type même du retour oblige l'appelant à traiter le cas absent — plus de surprise silencieuse.
4. Valider en entrée
import java.util.Objects;
public void setEmail(String email) {
this.email = Objects.requireNonNull(email, "email");
}
Échoue immédiatement et avec un message clair si le paramètre est null.
5. Utiliser les annotations @Nullable / @NonNull
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@NotNull
public String formatter(@NotNull String input, @Nullable String prefix) {
return (prefix != null ? prefix : "") + input.trim();
}
IntelliJ et les outils d'analyse statique vous alertent sur tout usage suspect avant même l'exécution.
6. Collections et chaînes vides plutôt que null
// ❌ L'appelant doit tester null
public List<User> getUsers() { return null; }
// ✅ Retourne une liste vide immuable — toujours sûre à itérer
public List<User> getUsers() { return List.of(); }
Le piège de l'auto-unboxing
Map<String, Integer> scores = new HashMap<>();
int s = scores.get("alice"); // ❌ NPE — get() renvoie Integer qui est null
// ✅ Utiliser getOrDefault
int s = scores.getOrDefault("alice", 0);
Diagnostic d'une NPE existante
- Lire la stack trace du bas vers le haut — la première ligne est le point d'erreur.
- Le message (sur Java 15+) indique quel objet était null.
- Chercher dans le code qui a pu laisser la référence à
null: méthode qui retourne null, champ jamais affecté, JSON mal parsé. - Ajouter une validation ou un
Optionalau bon endroit.
Règle d'or
Ne retournez jamais null depuis une méthode publique. Retournez Optional.empty(), une collection vide ou une valeur par défaut. Cette seule discipline élimine 80 % des NPE dans une base de code.