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 + множественное наследование | Events, Actions (Kotlin 1.9+) |
| object | Синглтон (декларативный) | Factory, Utility, Constants |
| 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 года. Мы проконсультируем вас и предложим наилучшее решение.