Kotlin — основна мова для Android-розробки. За даними Google Android Docs (2025), понад 95% нових проєктів на Android використовують Kotlin. Розуміння специфіки Kotlin — data class, sealed class, корутини та scope functions — обов'язкова вимога для Android-розробника.
Головне
Kotlin розширює концепції класів з Java. data class, sealed class, object та companion object — конструкції, яких немає в Java або вони реалізовані інакше.
data class — клас, який автоматично генерує equals(), hashCode(), toString(), copy() та componentN(). Ідеально для моделей даних (DTO, Entity). Вимоги: мінімум один параметр primary constructor, val/var, не може бути open/sealed/inner. sealed class — клас з обмеженою ієрархією підкласів. Усі підкласи відомі на етапі компіляції та оголошені в тому ж файлі. when-вираз із sealed class не потребує else-гілки. sealed interface (Kotlin 1.9+) — те саме, що sealed class, але дозволяє множинне успадкування. object — синглтон, оголошується ключовим словом object (не class). Thread-safe лінива ініціалізація. companion object — статичні члени класу. Має ім'я (за замовчуванням Companion). Може реалізовувати інтерфейси та мати extension функції.
| Тип | Опис | Застосування |
|---|---|---|
| data class | Автоматична генерація equals, hashCode, toString, copy | Моделі даних, DTO, Entity |
| sealed class | Обмежена ієрархія, перевірка when | Стани, Result, UI State |
| sealed interface | sealed class + множинне успадкування | Події, Дії (Kotlin 1.9+) |
| object | Синглтон (декларативний) | Factory, Utility, Константи |
| companion object | Статичні члени класу | Factory Method, статичні константи |
| enum class | Перелік з константами | Стани з фіксованим набором |
data class — для 90% моделей. sealed class — для UI State та Result. object — для синглтонів. IT Sectr рекомендує sealed class для всіх станів екрану (Loading, Success, Error).
Sealed class — потужний інструмент для моделювання станів. Приклад: UiState<T> з підкласами Loading, Success(data: T), Error(message: String). when-вираз гарантує обробку всіх станів. Sealed interface — для подій (events) та дій (actions), де потрібна множинна імплементація. Value class (Kotlin 1.5+) — обгортка для одного значення без overhead. Використовується для типобезпечних ідентифікаторів: @JvmInline value class UserId(val id: String).
Extension Function — додавання методу до існуючого класу без успадкування. fun String.isEmail(): Boolean. Extension Property — те саме для властивостей (без backing field). Inline Function — підстановка тіла функції в місце виклику — без overhead виклику. Використовується для higher-order функцій з лямбдами. Higher-Order Function — функція, яка приймає або повертає іншу функцію. Scope Functions — п'ять функцій для роботи з контекстом об'єкта: let, run, with, apply, also.
let — контекст it, повертає lambda result. Використовується для null-safe викликів (?.let {}). apply — контекст this, повертає контекст. Для конфігурації об'єкта. run — контекст this, повертає lambda result. Для обчислень з контекстом. also — контекст it, повертає контекст. Для side effects (логування). with — не extension, контекст this, повертає lambda result. Для групи операцій над об'єктом. Lambda — анонімна функція. Destructuring Declaration — розпакування data class на змінні: val (name, age) = person.
Inline function з reified — єдиний спосіб зберегти generic тип в JVM. Використовується для: типобезпечних білдерів (Gson.fromJson<T>()), перевірки типів (is T), отримання класу (T::class). Crossinline та Noinline — модифікатори для параметрів-лямбд в inline функціях. crossinline — забороняє non-local return, noinline — забороняє інлайн конкретної лямбди. IT Sectr рекомендує inline + reified тільки при роботі з типами, для звичайних higher-order функцій inline може збільшити розмір байткоду.
Корутини — легкі потоки для асинхронного програмування. Не блокують потік — призупиняються (suspend). suspend function — функція, яку можна призупинити без блокування потоку. Може викликатися тільки з корутини або іншої suspend функції.
CoroutineScope — область видимості корутин. Містить CoroutineContext (Job + Dispatcher). lifecycleScope — для Activity/Fragment (Lifecycle-aware). viewModelScope — для ViewModel (автоскасування при onCleared()). GlobalScope — глобальний (не використовувати в production — витоки пам'яті). Dispatchers: Dispatchers.Main (UI), Dispatchers.IO (мережа/диск), Dispatchers.Default (CPU-intensive), Dispatchers.Unconfined (не рекомендується). launch — запуск корутини: Job. async — запуск з результатом: Deferred<T>. runBlocking — блокуючий міст. withContext — зміна Dispatcher всередині suspend-функції.
// Приклад корутин: завантаження даних в 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)
}
}
}
}
// Паралельні запити з 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 — стандартний запуск корутини в ViewModel. withContext(Dispatchers.IO) — перемикання на IO-потік для мережевого запиту. Dispatchers визначають, на якому пулі потоків виконується корутина. IT Sectr рекомендує viewModelScope для ViewModel та lifecycleScope для Activity/Fragment.
reified — модифікатор типу в inline-функціях. Дозволяє використовувати тип: T::class, is T, as T. Без reified Generics в JVM стираються (type erasure). inline fun + reified — потужна комбінація для типобезпечних API. Destructuring Declaration — val (x, y) = point. Працює для data class та типів з componentN(). typealias — псевдонім типу: typealias Callback = (String) -> Unit. lateinit — відкладена ініціалізація var (для dependency injection). Потоконебезпечний. lazy — лінива ініціалізація val (thread-safe за замовчуванням). lazy(LazyThreadSafetyMode.NONE) — без синхронізації. Extension function та Extension property — додавання функціональності без успадкування. Kotlin — мова, де extension functions вирішують 90% завдань утиліт.
Delegated Properties — делегування getter/setter іншому об'єкту. Стандартні делегати: lazy, observable, vetoable, map. Кастомний делегат через getValue/setValue оператори. by — ключове слово делегування: val name by lazy { loadName() }. Delegated properties — основа для ViewModel делегатів (by viewModels()). IT Sectr рекомендує lazy для відкладеної ініціалізації та Delegates.observable для спостереження за змінами.
| Фіча | Опис | Приклад |
|---|---|---|
| reified | Збереження generic типу в inline | inline fun <reified T> parse(): T |
| destructuring | Розпакування data class | val (name, age) = person |
| typealias | Псевдонім типу | typealias Orders = List<Order> |
| lateinit | Відкладена var ініціалізація | lateinit var adapter: Adapter |
| lazy | Лінива val ініціалізація | val config by lazy { load() } |
| delegated | Делегування властивостей | var x by Delegates.observable(0) |
reified — для типобезпечних API. lazy — для відкладеного завантаження. delegated properties — для перевикористання логіки властивостей. IT Sectr рекомендує освоїти всі ці можливості для ефективної Kotlin-розробки.
Flow — холодний асинхронний потік даних в Kotlin. Емітить значення на вимогу колектора. StateFlow — гарячий Flow з єдиним поточним значенням. Використовується в ViewModel для UI State. SharedFlow — гарячий Flow для подій (one-shot events). flowOf, asFlow — створення Flow з колекцій. catch, retry, debounce — оператори. stateIn, shareIn — конвертація холодного Flow в гарячий. IT Sectr рекомендує StateFlow для UI State та SharedFlow для подій (Snackbar, навігація).
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 для JSON-серіалізації. @Serializable — анотація. @SerialName — кастомне ім'я поля. Підтримує: JSON, CBOR, ProtoBuf. Parcelize — @Parcelize для Android Parcelable (без ручної реалізації). Gson vs Moshi vs kotlinx: kotlinx.serialization — Kotlin-first, compile-safe, без reflection. Moshi — анотації + codegen. IT Sectr рекомендує kotlinx.serialization для нових проєктів та Moshi для існуючих.
@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
)
// Десеріалізація
val json = Json { ignoreUnknownKeys = true }
val response = json.decodeFromString<ApiResponse<List<User>>>(jsonString)
println("Users: ${response.data?.size ?: 0}")Часті запитання
data class — для даних (авто-генерація equals/hashCode/copy). sealed class — для ієрархії типів (перевірка в when). sealed interface — те саме з множинним успадкуванням.
let, run, with, apply, also. Різняться за контекстом (it vs this) та поверненням (result vs context). let — null safety, apply — конфігурація, also — side effects.
CoroutineScope — область корутин. lifecycleScope — для Activity, viewModelScope — для ViewModel. GlobalScope — не рекомендується.
reified — збереження типу в inline-функції. Дозволяє T::class та is T. Працює тільки з inline функціями.
launch — без результату. async — з результатом (Deferred). runBlocking — блокуючий міст для main/test. withContext — зміна Dispatcher.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.