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). Изисквания: поне един параметър в основния конструктор, 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 interface | sealed 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 — мощен инструмент за моделиране на състояния. Пример: 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 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, връща резултат от ламбда. Използва се за null-safe извиквания (?.let {}). apply — контекст this, връща контекст. За конфигурация на обект. run — контекст this, връща резултат от ламбда. За изчисления с контекст. also — контекст it, връща контекст. За странични ефекти (логиране). with — не е extension, контекст this, връща резултат от ламбда. За група операции върху обект. 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 — забранява inlining на конкретна ламбда. IT Sectr препоръчва inline + reified само при работа с типове; за обикновени higher-order функции, inline може да увеличи размера на байткода.
Корутини — леки нишки за асинхронно програмиране. Не блокират нишката — спират (suspend). suspend function — функция, която може да бъде спряна без блокиране на нишката. Може да бъде извикана само от корутина или друга suspend функция.
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 функция.
// Пример корутини: зареждане на данни в 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 (по подразбиране нишково безопасна). 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 тип в 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 за събития (еднократни събития). 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, безопасен по време на компилация, без рефлексия. 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 — същото с múltiple inheritance.
let, run, with, apply, also. Различават се по контекст (it vs this) и връщана стойност (result vs context). let — null безопасност, apply — конфигурация, also — странични ефекти.
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 г. Ще ви консултираме и ще предложим най-доброто решение.