Spécificités de Kotlin dans le développement mobile : ce que c'est, quelles constructions et comment ça fonctionne

Auteur : IT Sectr Publié le : 2026-06-29 Temps de lecture : 11 min

Kotlin est le langage principal pour le développement Android. Selon Google Android Docs (2025), plus de 95% des nouveaux projets Android utilisent Kotlin. Comprendre les spécificités de Kotlin — data class, sealed class, coroutines et scope functions — est une exigence obligatoire pour un développeur Android.

Points Clés

  • data class — génération automatique de equals/hashCode/toString/copy/componentN. Pour les modèles de données. sealed class — hiérarchie de types restreinte avec vérification when.
  • Scope functions : let, run, with, apply, also. Se différencient par le contexte (it vs this) et la valeur de retour.
  • Coroutines : launch (fire-and-forget), async (avec résultat), runBlocking (pont), withContext (changement de Dispatcher).
  • lifecycleScope et viewModelScope — coroutines Lifecycle-aware sans annulation manuelle.
  • reified — préservation du type dans les fonctions inline. lateinit/lazy — initialisation différée.

Classes (data class, sealed class, object, companion object)

Kotlin étend les concepts de classes de Java. data class, sealed class, object et companion object — des constructions qui n'existent pas en Java ou sont implémentées différemment.

data class vs sealed class

data class — une classe qui génère automatiquement equals(), hashCode(), toString(), copy() et componentN(). Idéal pour les modèles de données (DTO, Entity). Exigences : au moins un paramètre dans le constructeur primaire, val/var, ne peut pas être open/sealed/inner. sealed class — une classe avec une hiérarchie de sous-classes restreinte. Toutes les sous-classes sont connues à la compilation et déclarées dans le même fichier. L'expression when avec sealed class ne nécessite pas de branche else. sealed interface (Kotlin 1.9+) — identique à sealed class mais permet l'héritage multiple. object — un singleton, déclaré avec le mot-clé object (pas class). Initialisation paresseuse thread-safe. companion object — membres statiques d'une classe. A un nom (Companion par défaut). Peut implémenter des interfaces et avoir des extension functions.

Type Description Utilisation
data classGénération automatique de equals, hashCode, toString, copyModèles de données, DTO, Entity
sealed classHiérarchie restreinte, vérification whenÉtats, Résultat, UI State
sealed interfacesealed class + héritage multipleÉvénements, Actions (Kotlin 1.9+)
objectSingleton (déclaratif)Factory, Utility, Constantes
companion objectMembres statiques de classeFactory Method, constantes statiques
enum classÉnumération avec constantesÉtats avec ensemble fixe

data class — pour 90% des modèles. sealed class — pour UI State et Résultat. object — pour les singletons. IT Sectr recommande sealed class pour tous les états d'écran (Loading, Success, Error).

Sealed class en pratique

Sealed class — un outil puissant pour modéliser les états. Exemple : UiState<T> avec sous-classes Loading, Success(data: T), Error(message: String). L'expression when garantit le traitement de tous les états. Sealed interface — pour les événements et actions où une implémentation multiple est nécessaire. Value class (Kotlin 1.5+) — un wrapper pour une valeur unique sans overhead. Utilisé pour les identifiants type-safe : @JvmInline value class UserId(val id: String).

Fonctions (extension, inline, higher-order, scope functions)

Extension Function — ajouter une méthode à une classe existante sans héritage. fun String.isEmail(): Boolean. Extension Property — même chose pour les propriétés (sans backing field). Inline Function — insertion du corps de la fonction au site d'appel — sans overhead d'appel. Utilisé pour les higher-order functions avec lambdas. Higher-Order Function — une fonction qui prend ou retourne une autre fonction. Scope Functions — cinq fonctions pour travailler avec le contexte d'un objet : let, run, with, apply, also.

Scope Functions

let — contexte it, retourne le résultat de la lambda. Utilisé pour les appels null-safe (?.let {}). apply — contexte this, retourne le contexte. Pour la configuration d'objet. run — contexte this, retourne le résultat de la lambda. Pour les calculs avec contexte. also — contexte it, retourne le contexte. Pour les effets secondaires (logging). with — n'est pas une extension, contexte this, retourne le résultat de la lambda. Pour un groupe d'opérations sur un objet. Lambda — fonction anonyme. Destructuring Declaration — décompression de data class en variables : val (name, age) = person.

Inline + reified

Inline function avec reified — la seule façon de préserver un type générique dans la JVM. Utilisé pour : les builders type-safe (Gson.fromJson<T>()), la vérification de types (is T), l'obtention de la classe (T::class). Crossinline et Noinline — modificateurs pour les paramètres lambda dans les fonctions inline. crossinline — interdit le non-local return, noinline — interdit l'inlining d'une lambda spécifique. IT Sectr recommande inline + reified uniquement lors du travail avec les types ; pour les fonctions higher-order classiques, inline peut augmenter la taille du bytecode.

Coroutines (Coroutine Builder, Dispatchers, Scope)

Coroutines — des threads légers pour la programmation asynchrone. Ne bloquent pas le thread — se suspendent. suspend function — une fonction qui peut être suspendue sans bloquer le thread. Ne peut être appelée que depuis une coroutine ou une autre suspend function.

CoroutineScope

CoroutineScope — une portée pour les coroutines. Contient CoroutineContext (Job + Dispatcher). lifecycleScope — pour Activity/Fragment (Lifecycle-aware). viewModelScope — pour ViewModel (annulation automatique à onCleared()). GlobalScope — portée globale (déconseillé en production — fuites mémoire). Dispatchers : Dispatchers.Main (UI), Dispatchers.IO (réseau/disque), Dispatchers.Default (CPU-intensive), Dispatchers.Unconfined (déconseillé). launch — démarre une coroutine : Job. async — démarre avec résultat : Deferred<T>. runBlocking — pont bloquant. withContext — change de Dispatcher dans une suspend function.

kotlin
// Exemple de coroutines : chargement de données dans ViewModel
class MainViewModel : ViewModel() {
    private val _state = MutableStateFlow<UiState>(UiState.Loading)
    val state: StateFlow<UiState> = _state.asStateFlow()

    fun loadData() {
        viewModelScope.launch {
            _state.value = UiState.Loading
            try {
                val data = withContext(Dispatchers.IO) {
                    repository.fetchData()
                }
                _state.value = UiState.Success(data)
            } catch (e: Exception) {
                _state.value = UiState.Error(e.message)
            }
        }
    }
}

// Requêtes parallèles avec async
suspend fun loadCombinedData(): CombinedData = coroutineScope {
    val users = async(Dispatchers.IO) { api.getUsers() }
    val posts = async(Dispatchers.IO) { api.getPosts() }
    CombinedData(users.await(), posts.await())
}

viewModelScope.launch — lancement standard de coroutine dans ViewModel. withContext(Dispatchers.IO) — basculement vers le thread IO pour une requête réseau. Dispatchers déterminent sur quel pool de threads la coroutine s'exécute. IT Sectr recommande viewModelScope pour ViewModel et lifecycleScope pour Activity/Fragment.

Fonctionnalités avancées (reified, destructuring, lateinit/lazy)

reified — un modificateur de type dans les fonctions inline. Permet d'utiliser le type : T::class, is T, as T. Sans reified, les génériques dans la JVM sont effacés (type erasure). inline fun + reified — une combinaison puissante pour des APIs type-safe. Destructuring Declaration — val (x, y) = point. Fonctionne pour data class et les types avec componentN(). typealias — alias de type : typealias Callback = (String) -> Unit. lateinit — initialisation différée de var (pour l'injection de dépendances). Non thread-safe. lazy — initialisation paresseuse de val (thread-safe par défaut). lazy(LazyThreadSafetyMode.NONE) — sans synchronisation. Extension function et Extension property — ajouter des fonctionnalités sans héritage. Kotlin est un langage où les extension functions résolvent 90% des tâches utilitaires.

Propriétés Déléguées

Delegated Properties — déléguer getter/setter à un autre objet. Délégués standard : lazy, observable, vetoable, map. Délégué personnalisé via les opérateurs getValue/setValue. by — mot-clé de délégation : val name by lazy { loadName() }. Les propriétés déléguées sont la base des délégués ViewModel (by viewModels()). IT Sectr recommande lazy pour l'initialisation différée et Delegates.observable pour observer les changements.

Fonctionnalité Description Exemple
reifiedPréservation du type générique dans inlineinline fun <reified T> parse(): T
destructuringDécompression de data classval (name, age) = person
typealiasAlias de typetypealias Orders = List<Order>
lateinitInitialisation différée de varlateinit var adapter: Adapter
lazyInitialisation paresseuse de valval config by lazy { load() }
delegatedDélégation de propriétésvar x by Delegates.observable(0)

reified — pour des APIs type-safe. lazy — pour le chargement différé. delegated properties — pour réutiliser la logique des propriétés. IT Sectr recommande de maîtriser toutes ces fonctionnalités pour un développement efficace en Kotlin.

Flow et StateFlow

Flow — flux de données asynchrone froid en Kotlin. Émet des valeurs à la demande du collecteur. StateFlow — Flow chaud avec une seule valeur actuelle. Utilisé dans ViewModel pour UI State. SharedFlow — Flow chaud pour les événements (événements uniques). flowOf, asFlow — création de Flow à partir de collections. catch, retry, debounce — opérateurs. stateIn, shareIn — conversion de Flow froid en chaud. IT Sectr recommande StateFlow pour UI State et SharedFlow pour les événements (Snackbar, navigation).

kotlin
class SearchViewModel : ViewModel() {
    private val _query = MutableStateFlow("")
    val suggestions: StateFlow<List<String>> = _query
        .debounce(300)
        .filter { it.length >= 2 }
        .flatMapLatest { repository.search(it) }
        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())

    fun onQueryChanged(query: String) {
        _query.value = query
    }
}

Sérialisation (kotlinx.serialization, Parcelize)

kotlinx.serialization — bibliothèque Kotlin pour la sérialisation JSON. @Serializable — annotation. @SerialName — nom de champ personnalisé. Supporte : JSON, CBOR, ProtoBuf. Parcelize — @Parcelize pour Android Parcelable (sans implémentation manuelle). Gson vs Moshi vs kotlinx : kotlinx.serialization — Kotlin-first, compile-safe, sans reflection. Moshi — annotations + codegen. IT Sectr recommande kotlinx.serialization pour les nouveaux projets et Moshi pour les existants.

kotlin
@Serializable
data class ApiResponse<T>(
    val success: Boolean,
    @SerialName("data") val data: T? = null,
    val error: String? = null
)

@Serializable
data class User(
    val id: Int,
    val name: String,
    val email: String
)

// Désérialisation
val json = Json { ignoreUnknownKeys = true }
val response = json.decodeFromString<ApiResponse<List<User>>>(jsonString)
println("Users: ${response.data?.size ?: 0}")

Foire Aux Questions

Quelle est la différence entre data class et sealed class ?

data class — pour les données (génération automatique de equals/hashCode/copy). sealed class — pour la hiérarchie de types (vérification dans when). sealed interface — pareil avec héritage multiple.

Que sont les scope functions en Kotlin ?

let, run, with, apply, also. Se différencient par le contexte (it vs this) et la valeur de retour (result vs context). let — null safety, apply — configuration, also — effets secondaires.

Qu'est-ce que CoroutineScope et quels types existent ?

CoroutineScope — une portée pour les coroutines. lifecycleScope — pour Activity, viewModelScope — pour ViewModel. GlobalScope — déconseillé.

Qu'est-ce que reified en Kotlin ?

reified — préservation du type dans les fonctions inline. Permet T::class et is T. Fonctionne uniquement avec les fonctions inline.

Que sont les coroutine builders : launch, async, runBlocking ?

launch — sans résultat. async — avec résultat (Deferred). runBlocking — pont bloquant pour main/test. withContext — changement de Dispatcher.

Résumé

  • data class — pour les modèles. sealed class — pour les états. object — pour les singletons.
  • Scope functions : let (null-safe), apply (configuration), run (calculs), also (logging).
  • Coroutines : launch (fire-and-forget), async (avec résultat), withContext (changement de Dispatcher).
  • viewModelScope — standard pour ViewModel. lifecycleScope — pour Activity/Fragment.
  • reified — fonctions inline type-safe. lateinit — DI, lazy — initialisation paresseuse.
  • Extension functions — ajoutez des fonctionnalités sans héritage.
  • Dispatchers : Main (UI), IO (réseau/disque), Default (CPU). Choisissez le bon.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet