Le quartierK KotlinPièce 3/7Débutant

La sécurité du null

Comment Kotlin évite les plantages liés à l'absence de valeur, avec les types nullables, le safe call, l'opérateur Elvis et le cast sûr.

Ce que tu vas apprendre

  • Pourquoi null est dangereux et comment Kotlin t'en protège.
  • Utiliser ?, ?. et ?: pour gérer l'absence de valeur.
  • Savoir pourquoi éviter !!.

Le problème de null

null signifie « aucune valeur ». Une recette peut ne pas avoir de photo, un ingrédient peut ne pas avoir de note.

Si ton code utilise une valeur absente comme si elle existait, le programme plante. Dans de nombreux langages, cela donne l'erreur NullPointerException.

Kotlin traite ce problème dès la compilation : il te force à dire si une valeur peut être absente.

Types nullables

var titre: String = "Tarte"
// titre = null          // erreur de compilation

var photo: String? = "tarte.jpg"
photo = null             // accepté

Un type normal, comme String, ne peut jamais contenir null. Le compilateur refuse l'affectation.

Un type nullable s'écrit avec un ? après le nom du type : String?. Il accepte une chaîne ou null.

Le safe call ?.

val photo: String? = null
val longueur = photo?.length
println(longueur)   // null

Le safe call ?. appelle une propriété ou une fonction seulement si la valeur n'est pas null. Sinon, toute l'expression vaut null, sans plantage.

Le type de longueur est ici Int?, puisque le résultat peut être absent.

On peut chaîner plusieurs appels :

val pays = recette.auteur?.adresse?.pays

Dès qu'un maillon vaut null, le résultat entier vaut null.

L'opérateur Elvis ?:

val photo: String? = null
val longueur = photo?.length ?: 0
println(longueur)   // 0

L'opérateur Elvis ?: donne une valeur de secours. Si la partie gauche n'est pas null, il la renvoie. Sinon, il renvoie la partie droite.

Le résultat est maintenant un Int simple, plus un Int?. Tu peux t'en servir sans autre précaution.

fun noteMoyenne(id: Int): Int = recetteParId(id)?.note ?: 0

Ce mélange de ?. et de ?: est le réflexe à prendre.

Tester avec if

Le compilateur suit tes vérifications.

fun afficher(photo: String?) {
    if (photo != null) {
        println(photo.length)   // photo est traité comme String
    }
}

Dans le bloc du if, Kotlin sait que photo n'est pas null. Tu n'as pas besoin de ?.. On appelle cela un cast automatique.

let : agir seulement si présent

val photo: String? = "tarte.jpg"
photo?.let { println("Photo : $it") }

?.let { ... } exécute le bloc uniquement si la valeur existe. À l'intérieur, it désigne cette valeur, désormais non nulle. Si photo vaut null, rien ne se passe.

Le cast sûr as?

val valeur: Any = "Gratin"
val nombre: Int? = valeur as? Int       // null
val texte: String? = valeur as? String  // "Gratin"

as? convertit une valeur vers un type. Si la conversion est impossible, il renvoie null au lieu de lever une erreur.

!! : à éviter

val photo: String? = null
val longueur = photo!!.length   // NullPointerException

L'opérateur !! affirme « cette valeur n'est pas null ». Si elle l'est, le programme plante avec une NullPointerException. Tu retrouves alors le problème que Kotlin voulait éviter.

Évite !! dans ton code. Préfère ?. avec ?:, un if, ou ?.let. Réserve !! aux rares cas où tu es certain que la valeur existe, et où un plantage serait préférable à une valeur par défaut.

Quel outil choisir ?

BesoinOutilExemple
Autoriser l'absence?String?
Lire sans planter?.photo?.length
Une valeur de secours?:photo?.length ?: 0
Agir si présent?.letphoto?.let { ... }
Convertir sans erreuras?valeur as? Int

À retenir

  • Un type normal comme String n'accepte jamais null, c'est vérifié à la compilation.
  • String? est un type nullable : il accepte une chaîne ou null.
  • ?. appelle seulement si la valeur existe, sinon renvoie null.
  • ?: fournit une valeur de secours quand la partie gauche est null.
  • ?.let { ... } exécute un bloc seulement si la valeur est présente.
  • !! provoque une NullPointerException si la valeur est null : à éviter.

Pour aller plus loin

Sources officielles

Ensuite

Projet
Lignes de code
Niveau
Le quartier
Appartement
Kotlin
Pièce
3/7
Plan n°
kotlin/03.securite-du-null
Lignes de code · fiches rédigées à partir des documentations officielles, sources citées en bas de chaque page.