Kotlin специфика в мобилната разработка: какво е, какви конструкции и как работи

Автор: IT Sectr Публикувано: 2026-06-29 Време за четене: 11 мин

Kotlin е основният език за Android разработка. Според Google Android Docs (2025), над 95% от новите Android проекти използват Kotlin. Разбирането на Kotlin спецификата — data class, sealed class, корутини и scope functions — е задължително изискване за Android разработчик.

Основни точки

  • data class — автоматично генериране на equals/hashCode/toString/copy/componentN. За модели данни. sealed class — ограничена йерархия от типове с проверка when.
  • Scope functions: let, run, with, apply, also. Различават се по контекст (it vs this) и връщана стойност.
  • Корутини: launch (fire-and-forget), async (с резултат), runBlocking (мост), withContext (смяна на Dispatcher).
  • lifecycleScope и viewModelScope — Lifecycle-aware корутини без ръчно отменяне.
  • reified — запазване на типа в inline функции. lateinit/lazy — отложена инициализация.

Класове (data class, sealed class, object, companion object)

Kotlin разширява концепциите за класове от Java. data class, sealed class, object и companion object — конструкции, които не съществуват в Java или са имплементирани различно.

data class срещу sealed class

data class — клас, който автоматично генерира equals(), hashCode(), toString(), copy() и componentN(). Идеален за модели данни (DTO, Entity). Изисквания: поне един параметър в основния конструктор, val/var, не може да бъде open/sealed/inner. sealed class — клас с ограничена йерархия от подкласове. Всички подкласове са известни по време на компилация и са декларирани в същия файл. Изразът when със sealed class не изисква else клон. sealed interface (Kotlin 1.9+) — същото като sealed class, но позволява múltiple inheritance. object — сингълтън, деклариран с ключовата дума object (не class). Нишково безопасна ленива инициализация. companion object — статични членове на клас. Има име (по подразбиране Companion). Може да имплементира интерфейси и да има extension functions.

Тип Описание Употреба
data classАвтоматично генериране на equals, hashCode, toString, copyМодели данни, DTO, Entity
sealed classОграничена йерархия, проверка whenСъстояния, Резултат, UI State
sealed interfacesealed class + múltiple inheritanceСъбития, Действия (Kotlin 1.9+)
objectСингълтън (декларативен)Factory, Utility, Константи
companion objectСтатични членове на класаFactory Method, статични константи
enum classИзброяване с константиСъстояния с фиксиран набор

data class — за 90% от моделите. sealed class — за UI State и Резултат. object — за сингълтъни. IT Sectr препоръчва sealed class за всички състояния на екрана (Loading, Success, Error).

Sealed class на практика

Sealed class — мощен инструмент за моделиране на състояния. Пример: UiState<T> с подкласове Loading, Success(data: T), Error(message: String). Изразът when гарантира обработка на всички състояния. Sealed interface — за събития и действия, където е необходима múltiple имплементация. Value class (Kotlin 1.5+) — обвивка за единична стойност без overhead. Използва се за типобезопасни идентификатори: @JvmInline value class UserId(val id: String).

Функции (extension, inline, higher-order, scope functions)

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.

Scope Functions

let — контекст it, връща резултат от ламбда. Използва се за null-safe извиквания (?.let {}). apply — контекст this, връща контекст. За конфигурация на обект. run — контекст this, връща резултат от ламбда. За изчисления с контекст. also — контекст it, връща контекст. За странични ефекти (логиране). with — не е extension, контекст this, връща резултат от ламбда. За група операции върху обект. Lambda — анонимна функция. Destructuring Declaration — разопаковане на data class в променливи: val (name, age) = person.

Inline + reified

Inline function с reified — единственият начин да се запази generic тип в JVM. Използва се за: типобезопасни билдъри (Gson.fromJson<T>()), проверка на типове (is T), получаване на клас (T::class). Crossinline и Noinline — модификатори за ламбда параметри в inline функции. crossinline — забранява non-local return, noinline — забранява inlining на конкретна ламбда. IT Sectr препоръчва inline + reified само при работа с типове; за обикновени higher-order функции, inline може да увеличи размера на байткода.

Корутини (Coroutine Builder, Dispatchers, Scope)

Корутини — леки нишки за асинхронно програмиране. Не блокират нишката — спират (suspend). suspend function — функция, която може да бъде спряна без блокиране на нишката. Може да бъде извикана само от корутина или друга suspend функция.

CoroutineScope

CoroutineScope — обхват за корутини. Съдържа CoroutineContext (Job + Dispatcher). lifecycleScope — за Activity/Fragment (Lifecycle-aware). viewModelScope — за ViewModel (автоматично отменяне при onCleared()). GlobalScope — глобален обхват (не използвайте в продукция — изтичане на памет). Dispatchers: Dispatchers.Main (UI), Dispatchers.IO (мрежа/диск), Dispatchers.Default (CPU-intensive), Dispatchers.Unconfined (не се препоръчва). launch — стартира корутина: Job. async — стартира с резултат: Deferred<T>. runBlocking — блокиращ мост. withContext — сменя Dispatcher вътре в suspend функция.

kotlin
// Пример корутини: зареждане на данни в 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, destructuring, lateinit/lazy)

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 (по подразбиране нишково безопасна). 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() }. Делегираните свойства са основата за ViewModel делегати (by viewModels()). IT Sectr препоръчва lazy за отложена инициализация и Delegates.observable за наблюдение на промени.

Възможност Описание Пример
reifiedЗапазване на generic тип в inlineinline fun <reified T> parse(): T
destructuringРазопаковане на data classval (name, age) = person
typealiasПсевдоним на типtypealias Orders = List<Order>
lateinitОтложена инициализация на varlateinit var adapter: Adapter
lazyЛенива инициализация на valval config by lazy { load() }
delegatedДелегиране на свойстваvar x by Delegates.observable(0)

reified — за типобезопасни API. lazy — за отложено зареждане. delegated properties — за повторно използване на логика на свойства. IT Sectr препоръчва усвояването на всички тези възможности за ефективна Kotlin разработка.

Flow и StateFlow

Flow — студен асинхронен поток от данни в Kotlin. Излъчва стойности при поискване от колектора. StateFlow — горещ Flow с една текуща стойност. Използва се в ViewModel за UI State. SharedFlow — горещ Flow за събития (еднократни събития). flowOf, asFlow — създаване на Flow от колекции. catch, retry, debounce — оператори. stateIn, shareIn — конвертиране на студен Flow в горещ. IT Sectr препоръчва StateFlow за UI State и SharedFlow за събития (Snackbar, навигация).

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
    }
}

Сериализация (kotlinx.serialization, Parcelize)

kotlinx.serialization — Kotlin библиотека за JSON сериализация. @Serializable — анотация. @SerialName — персонализирано име на поле. Поддържа: JSON, CBOR, ProtoBuf. Parcelize — @Parcelize за Android Parcelable (без ръчна имплементация). Gson vs Moshi vs kotlinx: kotlinx.serialization — Kotlin-first, безопасен по време на компилация, без рефлексия. Moshi — анотации + codegen. IT Sectr препоръчва kotlinx.serialization за нови проекти и Moshi за съществуващи.

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
)

// Десериализация
val json = Json { ignoreUnknownKeys = true }
val response = json.decodeFromString<ApiResponse<List<User>>>(jsonString)
println("Users: ${response.data?.size ?: 0}")

Често задавани въпроси

Каква е разликата между data class и sealed class?

data class — за данни (автоматично генериране на equals/hashCode/copy). sealed class — за йерархия от типове (проверка в when). sealed interface — същото с múltiple inheritance.

Какво представляват scope functions в Kotlin?

let, run, with, apply, also. Различават се по контекст (it vs this) и връщана стойност (result vs context). let — null безопасност, apply — конфигурация, also — странични ефекти.

Какво е CoroutineScope и какви видове има?

CoroutineScope — обхват за корутини. lifecycleScope — за Activity, viewModelScope — за ViewModel. GlobalScope — не се препоръчва.

Какво е reified в Kotlin?

reified — запазване на типа в inline функции. Позволява T::class и is T. Работи само с inline функции.

Какво представляват coroutine builders: launch, async, runBlocking?

launch — без резултат. async — с резултат (Deferred). runBlocking — блокиращ мост за main/test. withContext — смяна на Dispatcher.

Резюме

  • data class — за модели. sealed class — за състояния. object — за сингълтъни.
  • Scope functions: let (null-безопасен), apply (конфигурация), run (изчисления), also (логиране).
  • Корутини: launch (fire-and-forget), async (с резултат), withContext (смяна на Dispatcher).
  • viewModelScope — стандарт за ViewModel. lifecycleScope — за Activity/Fragment.
  • reified — типобезопасни inline функции. lateinit — DI, lazy — ленива инициализация.
  • Extension functions — добавяйте функционалност без наследяване.
  • Dispatchers: Main (UI), IO (мрежа/диск), Default (CPU). Изберете правилния.

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта