Comment arrêter de vérifier null en Java sans perdre la raison

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

La malédiction de null : pourquoi écrivons-nous la même chose encore et encore ?

\n\n

Si vous codez en Java depuis plus d'une semaine, vous avez forcément rencontré NullPointerException. Et, très probablement, votre première réaction a été : « Ah, il suffit de vérifier ! ». Ainsi naissent des kilomètres de code comme celui-ci :

\n\n
if (user != null) {\n    if (user.getAddress() != null) {\n        String city = user.getAddress().getCity();\n        if (city != null) {\n            System.out.println(city.toUpperCase());\n        }\n    }\n}\n
\n\n

Ce code fonctionne. Mais il est laid. Il transforme la lecture de la logique en torture, et la maintenance en cauchemar. La question « How do I avoid checking for nulls in Java? » sur Stack Overflow a rassemblé des milliers de vues, et ce n'est pas un hasard. Chaque développeur Java se la pose tôt ou tard.

\n\n

Bonne nouvelle : éviter les vérifications de null est non seulement possible, mais aussi nécessaire. Java n'est pas JavaScript, et nous avons des outils pour écrire un code propre et sûr sans constructions « défensives ». Passons-les tous en revue — de la base aux techniques avancées.

\n\n

1. Optional<T> — votre meilleur allié

\n\n

Depuis Java 8, nous avons Optional. C'est un conteneur qui peut contenir une valeur ou être vide. Il est littéralement conçu pour éviter les vérifications de null et rendre le code plus déclaratif.

\n\n

Comment ça marche ?

\n\n

Au lieu de retourner null depuis une méthode, retournez Optional. Et au lieu de vérifications, utilisez des chaînes de méthodes.

\n\n
// Mauvais\npublic String getCity(User user) {\n    if (user == null) return "Inconnu";\n    Address address = user.getAddress();\n    if (address == null) return "Inconnu";\n    return address.getCity();\n}\n\n// Bon\npublic Optional<String> getCity(User user) {\n    return Optional.ofNullable(user)\n            .map(User::getAddress)\n            .map(Address::getCity);\n}\n\n// Utilisation\nString city = getCity(someUser).orElse("Inconnu");\n
\n\n

Remarquez : pas un seul if. map ne fonctionne que si la valeur n'est pas null. Si à n'importe quelle étape on rencontre null — la chaîne s'interrompt et vous obtenez Optional.empty().

\n\n

Méthodes populaires d'Optional

\n\n
    \n
  • orElse(T other) — retourner la valeur ou une alternative
  • \n
  • orElseGet(Supplier<? extends T> other) — version paresseuse, calculée seulement si nécessaire
  • \n
  • orElseThrow(Supplier<? extends X> exceptionSupplier) — lever votre propre exception
  • \n
  • ifPresent(Consumer<? super T> consumer) — exécuter une action si la valeur est présente
  • \n
  • filter(Predicate<? super T> predicate) — filtrer selon une condition
  • \n
\n\n
// Exemple avec filtre\nOptional<String> name = Optional.of("Java");\nname.filter(n -> n.startsWith("J"))\n    .ifPresent(System.out::println); // Affiche "Java"\n
\n\n

Important : Optional est conçu pour les valeurs de retour, pas pour les champs de classe ou les paramètres de méthode. N'en abusez pas.

\n\n

2. Objects.requireNonNull() — utilitaire pour des contrats explicites

\n\n

Parfois, null est une erreur et doit être détecté le plus tôt possible. Au lieu d'écrire des vérifications manuellement, utilisez java.util.Objects.requireNonNull().

\n\n
public class UserService {\n    private final UserRepository repository;\n\n    public UserService(UserRepository repository) {\n        this.repository = Objects.requireNonNull(repository, \n            "UserRepository ne doit pas être null");\n    }\n\n    public User findById(Long id) {\n        Objects.requireNonNull(id, "L'ID ne doit pas être null");\n        return repository.findById(id);\n    }\n}\n
\n\n

Cette approche s'appelle

Blogs

Book Recommendations