Kotlin is de primaire taal voor Android-ontwikkeling. Volgens Google Android Docs (2025) gebruikt meer dan 95% van de nieuwe Android-projecten Kotlin. Inzicht in Kotlin-specificaties — data class, sealed class, coroutines en scope functions — is een verplichte vereiste voor een Android-ontwikkelaar.
Belangrijkste punten
Kotlin breidt de klasseconcepten van Java uit. data class, sealed class, object en companion object — constructies die niet bestaan in Java of anders zijn geïmplementeerd.
data class — een klasse die automatisch equals(), hashCode(), toString(), copy() en componentN() genereert. Ideaal voor datamodellen (DTO, Entity). Vereisten: minimaal één parameter in de primaire constructor, val/var, kan niet open/sealed/inner zijn. sealed class — een klasse met een beperkte subklassehiërarchie. Alle subklassen zijn bekend tijdens compilatie en gedeclareerd in hetzelfde bestand. De when-expressie met sealed class heeft geen else-tak nodig. sealed interface (Kotlin 1.9+) — hetzelfde als sealed class, maar staat meervoudige overerving toe. object — een singleton, gedeclareerd met het sleutelwoord object (niet class). Thread-safe lazy-initialisatie. companion object — statische leden van een klasse. Heeft een naam (standaard Companion). Kan interfaces implementeren en extension functions hebben.
| Type | Beschrijving | Gebruik |
|---|---|---|
| data class | Automatische generatie van equals, hashCode, toString, copy | Datamodellen, DTO, Entity |
| sealed class | Beperkte hiërarchie, when-controle | Toestanden, Resultaat, UI State |
| sealed interface | sealed class + meervoudige overerving | Gebeurtenissen, Acties (Kotlin 1.9+) |
| object | Singleton (declaratief) | Factory, Utility, Constanten |
| companion object | Statische klasseleden | Factory Method, statische constanten |
| enum class | Opsomming met constanten | Toestanden met vaste set |
data class — voor 90% van de modellen. sealed class — voor UI State en Resultaat. object — voor singletons. IT Sectr beveelt sealed class aan voor alle schermtoestanden (Loading, Success, Error).
Sealed class — een krachtig hulpmiddel voor het modelleren van toestanden. Voorbeeld: UiState<T> met subklassen Loading, Success(data: T), Error(message: String). De when-expressie garandeert de afhandeling van alle toestanden. Sealed interface — voor gebeurtenissen en acties waar meerdere implementaties nodig zijn. Value class (Kotlin 1.5+) — een wrapper voor een enkele waarde zonder overhead. Gebruikt voor typeveilige identificatoren: @JvmInline value class UserId(val id: String).
Extension Function — een methode toevoegen aan een bestaande klasse zonder overerving. fun String.isEmail(): Boolean. Extension Property — hetzelfde voor eigenschappen (zonder backing field). Inline Function — het functielichaam invoegen op de aanroeplocatie — zonder aanroepoverhead. Gebruikt voor higher-order-functies met lambdas. Higher-Order Function — een functie die een andere functie accepteert of retourneert. Scope Functions — vijf functies om met de objectcontext te werken: let, run, with, apply, also.
let — context it, retourneert lambda-resultaat. Gebruikt voor null-safe aanroepen (?.let {}). apply — context this, retourneert context. Voor objectconfiguratie. run — context this, retourneert lambda-resultaat. Voor berekeningen met context. also — context it, retourneert context. Voor bijwerkingen (loggen). with — geen extension, context this, retourneert lambda-resultaat. Voor een groep bewerkingen op een object. Lambda — anonieme functie. Destructuring Declaration — data class uitpakken in variabelen: val (name, age) = person.
Inline function met reified — de enige manier om een generiek type in de JVM te behouden. Gebruikt voor: typeveilige builders (Gson.fromJson<T>()), typecontrole (is T), klasse ophalen (T::class). Crossinline en Noinline — modificatoren voor lambda-parameters in inline-functies. crossinline — verbiedt non-local return, noinline — verbiedt inlining van een specifieke lambda. IT Sectr beveelt inline + reified alleen aan bij het werken met typen; voor gewone higher-order-functies kan inline de bytecode-grootte vergroten.
Coroutines — lichtgewicht threads voor asynchroon programmeren. Ze blokkeren de thread niet — ze onderbreken (suspend). suspend function — een functie die kan worden onderbroken zonder de thread te blokkeren. Kan alleen worden aangeroepen vanuit een coroutine of een andere suspend function.
CoroutineScope — een bereik voor coroutines. Bevat CoroutineContext (Job + Dispatcher). lifecycleScope — voor Activity/Fragment (Lifecycle-aware). viewModelScope — voor ViewModel (automatisch annuleren bij onCleared()). GlobalScope — globaal bereik (niet gebruiken in productie — geheugenlekken). Dispatchers: Dispatchers.Main (UI), Dispatchers.IO (netwerk/schijf), Dispatchers.Default (CPU-intensief), Dispatchers.Unconfined (niet aanbevolen). launch — start een coroutine: Job. async — start met resultaat: Deferred<T>. runBlocking — blokkerende brug. withContext — wijzigt Dispatcher binnen een suspend function.
// Voorbeeld coroutines: gegevens laden in 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)
}
}
}
}
// Parallelle aanvragen met 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 — standaard coroutine-start in ViewModel. withContext(Dispatchers.IO) — overschakelen naar IO-thread voor netwerkverzoek. Dispatchers bepalen op welke threadpool de coroutine wordt uitgevoerd. IT Sectr beveelt viewModelScope aan voor ViewModel en lifecycleScope voor Activity/Fragment.
reified — een typemodificator in inline-functies. Maakt gebruik van het type mogelijk: T::class, is T, as T. Zonder reified worden generics in de JVM gewist (type erasure). inline fun + reified — een krachtige combinatie voor typeveilige API's. Destructuring Declaration — val (x, y) = point. Werkt voor data class en typen met componentN(). typealias — typealias: typealias Callback = (String) -> Unit. lateinit — uitgestelde initialisatie van var (voor dependency injection). Niet thread-safe. lazy — lazy-initialisatie van val (standaard thread-safe). lazy(LazyThreadSafetyMode.NONE) — zonder synchronisatie. Extension function en Extension property — functionaliteit toevoegen zonder overerving. Kotlin is een taal waar extension functions 90% van de hulptaken oplossen.
Delegated Properties — getter/setter delegeren aan een ander object. Standaard delegaten: lazy, observable, vetoable, map. Aangepaste delegatie via getValue/setValue-operatoren. by — delegatiesleutelwoord: val name by lazy { loadName() }. Gedelegeerde eigenschappen vormen de basis voor ViewModel-delegaten (by viewModels()). IT Sectr beveelt lazy aan voor uitgestelde initialisatie en Delegates.observable voor het observeren van wijzigingen.
| Functie | Beschrijving | Voorbeeld |
|---|---|---|
| reified | Generiek type behouden in inline | inline fun <reified T> parse(): T |
| destructuring | Data class uitpakken | val (name, age) = person |
| typealias | Typealias | typealias Orders = List<Order> |
| lateinit | Uitgestelde var-initialisatie | lateinit var adapter: Adapter |
| lazy | Lazy val-initialisatie | val config by lazy { load() } |
| delegated | Eigenschapsdelegatie | var x by Delegates.observable(0) |
reified — voor typeveilige API's. lazy — voor uitgesteld laden. delegated properties — voor herbruikbare eigenschapslogica. IT Sectr beveelt aan al deze functies te beheersen voor effectieve Kotlin-ontwikkeling.
Flow — koude asynchrone datastroom in Kotlin. Geeft waarden uit op verzoek van de collector. StateFlow — hete Flow met een enkele huidige waarde. Gebruikt in ViewModel voor UI State. SharedFlow — hete Flow voor gebeurtenissen (eenmalige gebeurtenissen). flowOf, asFlow — Flow maken van verzamelingen. catch, retry, debounce — operatoren. stateIn, shareIn — conversie van koude naar hete Flow. IT Sectr beveelt StateFlow aan voor UI State en SharedFlow voor gebeurtenissen (Snackbar, navigatie).
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
}
}kotlinx.serialization — Kotlin-bibliotheek voor JSON-serialisatie. @Serializable — annotatie. @SerialName — aangepaste veldnaam. Ondersteunt: JSON, CBOR, ProtoBuf. Parcelize — @Parcelize voor Android Parcelable (zonder handmatige implementatie). Gson vs Moshi vs kotlinx: kotlinx.serialization — Kotlin-first, compile-veilig, zonder reflectie. Moshi — annotaties + codegen. IT Sectr beveelt kotlinx.serialization aan voor nieuwe projecten en Moshi voor bestaande.
@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
)
// Deserialisatie
val json = Json { ignoreUnknownKeys = true }
val response = json.decodeFromString<ApiResponse<List<User>>>(jsonString)
println("Users: ${response.data?.size ?: 0}")Veelgestelde vragen
data class — voor gegevens (automatische generatie van equals/hashCode/copy). sealed class — voor typehiërarchie (controle in when). sealed interface — hetzelfde met meervoudige overerving.
let, run, with, apply, also. Verschillen per context (it vs this) en retourwaarde (result vs context). let — nullveiligheid, apply — configuratie, also — bijwerkingen.
CoroutineScope — een bereik voor coroutines. lifecycleScope — voor Activity, viewModelScope — voor ViewModel. GlobalScope — niet aanbevolen.
reified — typebehoud in inline-functies. Maakt T::class en is T mogelijk. Werkt alleen met inline-functies.
launch — zonder resultaat. async — met resultaat (Deferred). runBlocking — blokkerende brug voor main/test. withContext — Dispatcher wijzigen.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.