object у Kotlin: синтаксис і практичне застосування синглтон-об'єктів

Автор: IT Sectr Опубліковано: 2026-06-21 Час читання: 9 хв

object у Kotlin — це декларативний спосіб створення синглтон-об'єкта з лінивою ініціалізацією та потокобезпечністю за замовчуванням. Ключове слово object замінює цілий клас з єдиним екземпляром і використовується для оголошення singleton, companion object, анонімних об'єктів і статичних утиліт. Згідно з JetBrains Kotlin Documentation (2026), object declaration — найпростіший і найбезпечніший спосіб реалізації singleton у JVM-світі.

Головне

  • object — ключове слово для оголошення синглтон-класу з єдиним екземпляром
  • Лінива ініціалізація — object створюється при першому зверненні, а не при завантаженні класу
  • Companion object — аналог статичних членів у Kotlin (немає static keyword)
  • Object expression — анонімний об'єкт для перевизначення методів на льоту
  • Потокобезпечність — ініціалізація object гарантовано thread-safe

Що таке object у Kotlin?

object у Kotlin — це спеціальна форма оголошення, яка одночасно визначає клас і створює його єдиний екземпляр (синглтон). Це гібрид class declaration і instance creation в одній конструкції.

У Java для створення singleton потрібно написати приватний конструктор, статичне поле, метод getInstance і опрацювати потокобезпечність. Kotlin object робить це одним рядком коду: object MySingleton { }. Компілятор самостійно генерує потокобезпечну ліниву ініціалізацію, використовуючи механізм static initializer у байт-коді JVM.

За даними Kotlin Language Specification (2026), object declaration компілюється у фінальний клас з приватним конструктором і статичним полем INSTANCE, ініціалізованим у статичному блоці. Це гарантує атомарність ініціалізації на рівні JVM.

Синглтон-об'єкти (object declaration)

Object declaration (синглтон-об'єкт) оголошується за допомогою ключового слова object, за яким слідує ім'я. Тіло об'єкта може містити властивості, методи, init-блоки та успадковувати інші класи або інтерфейси.

kotlin
object DatabaseManager {
    private val connection: String = "jdbc:postgresql://localhost:5432/app"
    
    fun query(sql: String): List<Map<String, Any>> {
        // виконання запиту
        return emptyList()
    }
}

// Використання
DatabaseManager.query("SELECT * FROM users")

Ініціалізація DatabaseManager відбувається в момент першого звернення — ліниво та потокобезпечно. Жодного додаткового коду для синхронізації не потрібно.

Успадкування для object

Object може успадковувати звичайні класи та інтерфейси. Це дозволяє використовувати object як реалізацію абстрактного класу або інтерфейсу з єдиним екземпляром.

kotlin
interface Logger {
    fun log(message: String)
}

object ConsoleLogger : Logger {
    override fun log(message: String) {
        println("[LOG] $message")
    }
}

Companion object

companion object — це спеціальний object, оголошений всередині класу з ключовим словом companion. Він замінює статичні члени в Kotlin, оскільки в мові немає ключового слова static.

kotlin
class ApiClient {
    companion object {
        private const val BASE_URL = "https://api.example.com"
        
        fun create(): ApiClient {
            return ApiClient()
        }
    }
}

// Виклик без створення екземпляра ApiClient
val client = ApiClient.create()

Companion object може мати ім'я (за замовчуванням Companion), реалізовувати інтерфейси та бути розширюваним через extension functions. На відміну від статичних методів у Java, companion object — це повноцінний об'єкт, який може бути переданий як аргумент або збережений у змінну.

За даними Kotlin Best Practices (2026), companion object використовується для фабричних методів, констант і статичних утиліт, пов'язаних з класом. При цьому рекомендується уникати надмірного використання companion object — для непов'язаних утиліт краще застосовувати топ-рівневі функції.

Анотація @JvmStatic

Для сумісності з Java companion object можна анотувати методами @JvmStatic. Це генерує справжній статичний метод у байт-коді JVM, доступний з Java-коду без синтаксису Companion.

Object expressions (анонімні об'єкти)

Object expression — це анонімний об'єкт, створюваний на місці для перевизначення методів класу або інтерфейсу без оголошення окремого іменованого класу.

kotlin
val handler = object : Runnable {
    override fun run() {
        println("Завдання виконано")
    }
}

thread(handler)

Object expressions відрізняються від оголошень object тим, що вони створюють новий екземпляр при кожному виконанні. Вони не є синглтонами і не мають імені. Анонімні об'єкти можуть захоплювати змінні з замикання, як і лямбди.

На відміну від Java, де анонімні класи можуть успадковувати лише один тип, Kotlin object expression може успадковувати кілька типів одночасно.

kotlin
interface Clickable {
    fun click()
}

abstract class View {
    abstract fun render()
}

val button = object : View(), Clickable {
    override fun render() = println("Рендеринг кнопки")
    override fun click() = println("Кнопку натиснуто")
}

Практичні сценарії використання

Object — одна з найуніверсальніших конструкцій Kotlin, що застосовується в багатьох сценаріях.

Repository синглтони

В Android-проєктах object часто використовується для оголошення Repository, де не потрібно множинних екземплярів. Єдиний екземпляр гарантує консистентність даних.

kotlin
object UserRepository {
    fun getUser(id: Int): User? {
        // отримання користувача
        return null
    }
}

Фабричні методи через companion object

Companion object з фабричними методами — альтернатива множинним конструкторам. Named factory methods роблять код самодокументованим.

kotlin
data class GsonParser {
    companion object {
        fun create(): GsonParser = GsonParser()
        fun createPretty(): GsonParser = GsonParser()
    }
}

Константи та перелічення

Object може слугувати контейнером для констант, замінюючи статичні final поля в Java. При цьому object підтримує успадкування, що дозволяє створювати ієрархії конфігурацій.

За даними Kotlin Standard Library (2026), object declaration є найбільш продуктивним способом створення singleton у Kotlin, перевершуючи за швидкістю double-checked locking реалізації та порівнянний з enum singleton у Java.

Часті запитання

Чим object відрізняється від звичайного класу?

Object одночасно оголошує клас і створює його єдиний екземпляр. Звичайний клас може мати безліч екземплярів, створюваних через конструктор.

Коли ініціалізується object declaration?

Ліниво — при першому зверненні до об'єкта. До цього пам'ять не виділяється і код в init-блоці не виконується.

Чи може object мати конструктор?

Ні, object не може мати явного конструктора. Ініціалізація виконується в init-блоці, який викликається один раз при першому доступі до об'єкта.

Чим companion object відрізняється від звичайного object?

companion object — це object, оголошений всередині класу. Його члени доступні через ім'я класу без створення екземпляра, що замінює статичні члени Java.

Чи безпечні object declarations у багатопотоковому середовищі?

Так, ініціалізація object повністю потокобезпечна завдяки статичному ініціалізатору JVM. Жодна додаткова синхронізація не потрібна.

Підсумки

  • object — декларативний синглтон з лінивою та потокобезпечною ініціалізацією
  • companion object — статичні члени в Kotlin, фабричні методи, константи
  • Object expression — анонімні об'єкти на місці з захопленням змінних з замикання
  • Успадкування — object може успадковувати класи та інтерфейси, включаючи кілька типів
  • Продуктивність — ініціалізація через static initializer JVM, без overhead double-checked locking
  • Застосування — singleton-сервіси, repository, константи, фабрики, listener-адаптери
  • Обмеження — немає явного конструктора, один екземпляр на всю JVM

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також