ProgrammationDéveloppeur Android

Comment fonctionne la propriété initialisée tardivement ('lateinit var') en Kotlin, en quoi est-elle différente des propriétés nullables et dans quelles situations doit-on l'utiliser ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Historique de la question

Kotlin se concentre sur la sécurité des types et évite les pointeurs nuls, mais il arrive souvent qu'il soit nécessaire d'initialiser des variables de manière tardive (late), par exemple lors de l'utilisation de l'injection de dépendances ou dans une activité Android. Pour cela, le modificateur lateinit a été ajouté.

Problème

Les propriétés ordinaires nécessitent une initialisation obligatoire ou doivent être nullables, ce qui est gênant lorsque l'initialisation tardive mais obligatoire est garantie. L'utilisation du type nullable complique le code et nécessite des vérifications null supplémentaires.

Solution

lateinit permet de créer une propriété non initialisée jusqu'à un certain point, mais de promettre au compilateur qu'elle sera initialisée avant la première utilisation. L'initialisation peut se faire non pas dans le constructeur, mais plus tard.

class UserViewModel { lateinit var repository: UserRepository fun onCreate() { repository = UserRepository() } fun getData() = repository.load() }

Caractéristiques clés :

  • Permet de ne pas utiliser null tout en reportant l'initialisation
  • lance UninitializedPropertyAccessException lorsqu'on accède à une propriété lateinit non initialisée
  • Seulement pour var et pas pour les types primitifs (Int, Double, etc.)

Questions piégeuses.

Peut-on utiliser lateinit pour des propriétés val ?

Non. lateinit ne fonctionne qu'avec var, car val doit être initialisé une fois immédiatement ou via un getter.

Est-ce que lateinit fonctionne avec des types Int, Boolean, Double et d'autres primitifs ?

Non. Seulement avec des types de référence d'objet. Pour les primitifs, utilisez des types nullables.

Que se passe-t-il si on accède à une propriété lateinit avant son initialisation ?

Kotlin lancera UninitializedPropertyAccessException :

lateinit var foo: String println(foo) // Exception

Erreurs typiques et anti-patrons

  • Oublié d'initialiser une propriété lateinit — l'application va planter
  • Utiliser là où une sémantique nullable est nécessaire avec une vérification isInitialized
  • Applicabilité pour des types primitifs et val

Exemple de la vie réelle

Cas négatif

Un développeur a déclaré lateinit var item: String, n'ayant pas initialisé avant le premier appel de la méthode getItem. Résultat : crash de l'application.

Avantages:

  • Élimine le nullable, si tout est initialisé correctement

Inconvénients:

  • Risque de confondre le cycle de vie et de provoquer une exception d'exécution

Cas positif

Activité Android : lateinit var presenter, initialisation dans onCreate. L'utilisation de presenter dans toutes les méthodes de cycle de vie est sécurisée : la nullabilité n'est pas nécessaire.

Avantages:

  • Améliore la lisibilité, évite des vérifications inutiles
  • Garantit une initialisation obligatoire

Inconvénients:

  • Nécessité de surveiller clairement l'ordre d'appel de l'initialisation