Companion object în Kotlin: ce este, sintaxa și aplicare

Autor: IT Sectr Publicat: 2026-06-21 Timp de citire: 9 min

companion object — mecanismul limbajului Kotlin care înlocuiește cuvântul cheie static din Java pentru declararea membrilor statici ai clasei. În Kotlin nu există static încorporat — în schimb se folosește declarația object cu modificatorul companion în interiorul clasei. Conform JetBrains, 2025, companion object permite apelarea metodelor și proprietăților prin numele clasei, ceea ce le face echivalentul complet al membrilor statici în ecosistemul Java.

Principalele puncte

  • companion object — declarație object în interiorul clasei cu cuvântul cheie companion, înlocuind Java static
  • Membrii statici sunt accesibili prin numele clasei fără a crea o instanță: ClassName.method()
  • Companion object numit permite atribuirea unui nume obiectului pentru un cod mai lizibil
  • Interfețele în Kotlin pot conține de asemenea companion object cu implementări de metode
  • @JvmStatic — adnotare pentru exportarea metodelor companion object ca metode static reale în Java

Ce este companion object în Kotlin?

companion object — este o varietate specială de object declaration în limbajul Kotlin, marcată cu cuvântul cheie companion. Aceasta permite declararea membrilor care aparțin clasei, nu instanțelor sale — adică membri statici în terminologia Java. Spre deosebire de Java, unde static este un modificator pentru câmpuri și metode individuale, în Kotlin membrii statici sunt grupați într-un singur obiect companion.

Orice clasă în Kotlin poate conține exact un companion object. Membrii acestui obiect sunt accesibili prin numele clasei fără a crea o instanță: MyClass.method(). În același timp, din perspectiva bytecode-ului, companion object este compilat într-o clasă internă separată, iar metodele sale devin metode statice ale clasei exterioare atunci când se folosește adnotarea @JvmStatic.

Conform Google I/O 2024, companion object a devenit modelul principal pentru metode de fabrică, constante și funcții utilitare în aplicațiile Android moderne în Kotlin. Dezvoltatorii îl aleg în locul claselor utilitare cu funcții de pachet, deoarece companion object păstrează legătura logică cu clasa proprietară.

Folosiți companion object pentru gruparea contextului static — constante, fabrici, metode auxiliare care se referă logic la clasă, dar nu necesită o instanță.

Sintaxa companion object: declarație și acces

Sintaxa de bază a companion object este simplă: cuvântul cheie companion se plasează înaintea declarației object în interiorul clasei. Dacă numele nu este specificat, obiectul primește numele Companion, la care se poate face referire explicit sau implicit.

kotlin
class User {
    companion object {
        const val TABLE_NAME = "users"

        fun create(name: String): User {
            return User(name)
        }
    }

    val name: String
    constructor(name: String) { this.name = name }
}

// Acces prin numele clasei
val table = User.TABLE_NAME
val user = User.create("Alice")

În exemplul de mai sus TABLE_NAME și create() sunt accesibile prin User.TABLE_NAME și User.create(). Observați modificatorul const pentru constantele primitive — el garantează încorporarea valorii în faza de compilare, similar cu Java static final pentru primitive și String.

Acces implicit și explicit prin Companion

Dacă companion object nu are nume, se poate accesa prin numele automat Companion: User.Companion.TABLE_NAME. În practică, acest lucru este rar necesar, dar util la apelarea din cod Java sau la utilizarea reflexiei.

kotlin
// Ambele apeluri sunt echivalente
User.create("Bob")
User.Companion.create("Bob")

// Obținerea referinței la companion object
val companion: User.Companion = User

Companion object numit și particularități

companion object poate avea un nume, ceea ce îmbunătățește lizibilitatea codului și permite referirea la el printr-un nume clar. Factory — este cel mai comun nume pentru companion object utilizat ca fabrică.

kotlin
class HttpResponse {
    companion object Factory {
        fun ok(body: String): HttpResponse = HttpResponse(200, body)
        fun notFound(): HttpResponse = HttpResponse(404, "Not Found")
        fun serverError(): HttpResponse = HttpResponse(500, "Internal Error")
    }
}

// Acces prin numele Factory
val response = HttpResponse.Factory.ok("data")

Companion object numit ajută la documentarea scopului membrilor statici. În refactorizare, numele face codul auto-documentat — dezvoltatorul vede imediat că Factory creează instanțe HttpResponse.

Limitare: exact un companion object per clasă

O clasă poate conține doar un companion object. Aceasta este o diferență fundamentală față de Java, unde se pot declara oricâte câmpuri și metode statice fără grupare. Dacă sunt necesare mai multe grupuri logice de membri statici, folosiți object declarations imbricate fără companion.

Conform documentației oficiale Kotlin (Kotlin Docs, 2025), limitarea la un companion object este motivată de designul limbajului: membrii statici trebuie să fie strâns legați de clasă, iar un singur obiect companion asigură o graniță clară a acestei legături. Dacă sunt prea mulți membri statici — acesta este un semnal pentru refactorizarea clasei.

Companion object în interfețe

În Kotlin, interfețele pot conține de asemenea companion object. Acest lucru permite definirea metodelor statice și constantelor direct în interiorul interfeței, ceea ce nu este posibil în Java. Această abordare este adesea folosită pentru declararea constantelor asociate interfeței sau a metodelor de fabrică.

kotlin
interface ApiService {
    companion object {
        const val BASE_URL = "https://api.example.com"
        const val TIMEOUT_MS = 5000

        fun create(client: OkHttpClient): ApiService =
            Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .build()
                .create(ApiService::class.java)
    }
}

În acest exemplu, BASE_URL, TIMEOUT_MS și create() aparțin interfeței ApiService, nu implementărilor sale. Este convenabil: toate constantele și logica de fabrică pentru crearea instanței serviciului API se află într-un singur loc — în interiorul interfeței însăși.

Implementările interfeței nu moștenesc membrii companion object — aceștia se apelează doar prin numele interfeței: ApiService.BASE_URL.

@JvmStatic și @JvmField: compatibilitate cu Java

La apelarea metodelor companion object din cod Java, acestea sunt disponibile implicit ca metode ale clasei imbricate Companion, nu ca metode statice ale clasei exterioare. Pentru a le exporta ca metode și câmpuri static reale pentru Java, folosiți adnotarea @JvmStatic pentru metode și @JvmField pentru câmpuri.

AdnotareAplicareRezultat în Java
@JvmStaticMetode companion objectMetodă statică: ClassName.method()
@JvmFieldCâmpuri companion objectCâmp static: ClassName.field
constPrimitive și StringConstantă inline: compilatorul înlocuiește valoarea
fără adnotareMetode/câmpuri impliciteCompanion.method() / Companion.field
kotlin
class MathUtils {
    companion object {
        const val PI = 3.14159

        @JvmStatic
        fun square(x: Int): Int = x * x

        @JvmField
        val TAG: String = "MathUtils"
    }
}

// Apelat în Java ca MathUtils.square(5), MathUtils.TAG

Utilizarea @JvmStatic este recomandată pentru toate metodele publice ale companion object care trebuie să fie accesibile din cod Java. const se aplică doar tipurilor primitive și String — pentru celelalte tipuri folosiți @JvmField.

Exemple practice de utilizare a companion object

În proiecte reale, companion object este utilizat pentru câteva scenarii standard. Metodele de fabrică — cel mai comun model: în locul mai multor constructori cu semnături diferite, se folosesc metode de fabrică denumite în companion object.

kotlin
sealed class NetworkResult<out T> {
    data class Success<out T>(val data: T) : NetworkResult<T>()
    data class Error(val message: String) : NetworkResult<Nothing>()

    companion object {
        fun loading<T>(): NetworkResult<T> =
            Loading()
    }
}

private class Loading<T> : NetworkResult<T>()

companion object din NetworkResult oferă metoda de fabrică loading() care creează o instanță Loading cu tipul generic corect. Fără această metodă, ar trebui să creați instanța direct prin Loading(), ceea ce dezvăluie implementarea internă.

Constante și taguri pentru logare

Adesea companion object este folosit pentru stocarea constantelor specifice clasei. Constantele declarate cu const val sunt încorporate în faza de compilare, oferind un overhead zero în runtime.

kotlin
class UserRepository {
    companion object {
        private const val TAG = "UserRepository"
        private const val CACHE_SIZE = 100
        private const val DEFAULT_PAGE_SIZE = 20
    }
}

Întrebări frecvente

Cu ce se deosebește companion object de object obișnuit în Kotlin?

ordinary object — este un singleton complet, care există independent de clasă. companion object — este un object în interiorul clasei, ai cărui membri sunt apelați prin numele clasei exterioare. În bytecode, companion object devine o clasă imbricată statică, iar object obișnuit devine o clasă singleton autonomă.

Se poate moșteni companion object?

Nu, companion object nu este moștenit de subclase. Dacă clasa B moștenește clasa A, B.method() nu va apela metoda din companion object al clasei A — trebuie să accesați prin A.method(). Aceasta corespunde comportamentului metodelor statice în Java.

Cum se apelează companion object din cod Java?

Implicit — prin ClassName.Companion.method(). Pentru a apela ca metodă statică, adăugați @JvmStatic la metoda companion object. Pentru câmpuri folosiți @JvmField sau declarați-le cu const val pentru primitive.

De ce Kotlin nu are cuvântul cheie static?

Dezvoltatorii Kotlin au decis să renunțe la static în favoarea companion object pentru o lucrare uniformă cu obiectele. static în Java încalcă principiile OOP, deoarece metodele statice nu sunt legate de o instanță. companion object — este un obiect de primă clasă care poate fi transmis, extins cu funcții de extensie și poate implementa interfețe.

Companion object afectează performanța?

La utilizarea const val pentru primitive și String — overhead zero, valoarea este încorporată în bytecode. Pentru metode nu există overhead dacă metoda nu este inline. În majoritatea cazurilor, companion object nu are un impact măsurabil asupra performanței. Folosiți @JvmStatic doar pentru API-ul public apelat din Java.

Rezumat

  • companion object — mecanismul Kotlin pentru declararea membrilor statici ai clasei, înlocuind Java static
  • Un companion object per clasă — grupează toate elementele statice într-un singur obiect companion
  • Acces prin numele clasei: ClassName.method() sau ClassName.Companion.method()
  • @JvmStatic și @JvmField exportă membrii ca metode și câmpuri static reale pentru Java
  • const val pentru primitive și String — încorporează valoarea în faza de compilare fără overhead
  • Interfețele suportă de asemenea companion object pentru constante și metode de fabrică
  • Companion object numit îmbunătățește lizibilitatea codului și auto-documentează scopul membrilor statici

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și