companion object — a Kotlin nyelv mechanizmusa, amely a Java static kulcsszavát helyettesíti az osztály statikus tagjainak deklarálásához. Kotlinban nincs beépített static — helyette az object deklarációt használjuk a companion módosítóval az osztályon belül. A JetBrains, 2025 szerint a companion object lehetővé teszi metódusok és tulajdonságok meghívását az osztály neve által, ami teljes mértékben megfelel a statikus tagoknak a Java ökoszisztémában.
Fő pontok
companion object — az object declaration egy speciális fajtája Kotlinban, amelyet a companion kulcsszó jelöl. Lehetővé teszi olyan tagok deklarálását, amelyek az osztályhoz tartoznak, nem pedig az példányaihoz — vagyis statikus tagokat a Java terminológiájában. Ellentétben Java-val, ahol a static módosító egyedi mezőkhöz és metódusokhoz tartozik, Kotlinban a statikus tagok egyetlen társ-objektumon belül csoportosulnak.
Bármely osztály Kotlinban pontosan egy companion object-et tartalmazhat. Ennek az objektumnak a tagjai az osztály neve által érhetők el példány létrehozása nélkül: MyClass.method(). Ugyanakkor bájtkód szempontjából a companion object egy külön belső osztállyá fordul, metódusai pedig a külső osztály statikus metódusaivá válnak a @JvmStatic annotáció használatakor.
A Google I/O 2024 szerint a companion object a fő mintává vált a gyártó metódusok, konstansok és segédfüggvények számára modern Kotlin Android alkalmazásokban. A fejlesztők a segédosztályok helyett választják, mivel a companion object megtartja a logikai kapcsolatot a tulajdonos osztállyal.
Használja a companion object-et statikus kontextus csoportosításához — konstansok, gyárak, segédmetódusok, amelyek logikailag az osztályhoz tartoznak, de nem igényelnek példányt.
A companion object alapszintaxisa egyszerű: a companion kulcsszó az object deklaráció elé kerül az osztályon belül. Ha nincs név megadva, az objektum a Companion nevet kapja, amelyre explicit vagy implicit módon lehet hivatkozni.
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 }
}
// Hozzáférés az osztály neve által
val table = User.TABLE_NAME
val user = User.create("Alice")
A fenti példában a TABLE_NAME és a create() a User.TABLE_NAME és User.create() által érhető el. Figyelje meg a const módosítót a primitív konstansokhoz — ez garantálja az érték beépítését fordítási időben, hasonlóan a Java static final-hez primitívek és String esetén.
Ha a companion object-nek nincs neve, akkor az automatikus Companion néven keresztül érhető el: User.Companion.TABLE_NAME. Gyakorlatban ez ritkán szükséges, de hasznos Java kódból történő hívásnál vagy reflektálásnál.
// Mindkét hívás egyenértékű
User.create("Bob")
User.Companion.create("Bob")
// Hivatkozás szerzése a companion object-re
val companion: User.Companion = User
A companion object-nek lehet neve, ami javítja a kód olvashatóságát és lehetővé teszi a hivatkozást egy érthető néven. Factory — a leggyakoribb név a gyártóként használt companion object számára.
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")
}
}
// Hozzáférés a Factory néven keresztül
val response = HttpResponse.Factory.ok("data")
A nevesített companion object segít dokumentálni a statikus tagok célját. Refaktorálásnál a név öndokumentálóvá teszi a kódot — a fejlesztő azonnal látja, hogy a Factory HttpResponse példányokat hoz létre.
Egy osztály csak egy companion object-et tartalmazhat. Ez alapvető különbség Java-hoz képest, ahol tetszőleges számú statikus mező és metódus deklarálható csoportosítás nélkül. Ha több logikai csoport statikus tagra van szükség, használjon beágyazott object deklarációkat companion nélkül.
A hivatalos Kotlin dokumentáció szerint (Kotlin Docs, 2025) az egy companion object korlátozást a nyelv tervezése indokolja: a statikus tagoknak szorosan kell kapcsolódniuk az osztályhoz, és egy társ-objektum biztosítja e kapcsolat egyértelmű határát. Ha túl sok a statikus tag — ez az osztály refaktorálásának jele.
Kotlinban az interfészek is tartalmazhatnak companion object-et. Ez lehetővé teszi statikus metódusok és konstansok közvetlen meghatározását az interfészen belül, ami Java-ban nem lehetséges. Ezt a megközelítést gyakran használják az interfészhez kapcsolódó konstansok vagy gyártó metódusok deklarálására.
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)
}
}
Ebben a példában a BASE_URL, a TIMEOUT_MS és a create() az ApiService interfészhez tartozik, nem annak implementációihoz. Ez kényelmes: az API szolgáltatás példányának létrehozásához szükséges összes konstans és gyártó logika egy helyen — magában az interfészben található.
Az interfész implementációi nem öröklik a companion object tagjait — azok csak az interfész neve által hívhatók: ApiService.BASE_URL.
A companion object metódusainak Java kódból történő hívásakor alapértelmezés szerint a Companion beágyazott osztály metódusaiként érhetők el, nem a külső osztály statikus metódusaiként. Ahhoz, hogy valódi static metódusokként és mezőkként exportálja őket Java-ba, használja a @JvmStatic annotációt metódusokhoz és a @JvmField annotációt mezőkhöz.
| Annotáció | Alkalmazás | Eredmény Java-ban |
|---|---|---|
| @JvmStatic | Companion object metódusok | Statikus metódus: ClassName.method() |
| @JvmField | Companion object mezők | Statikus mező: ClassName.field |
| const | Primitívek és String | Inline konstans: fordító behelyettesíti |
| annotáció nélkül | Alapértelmezett metódusok/mezők | Companion.method() / Companion.field |
class MathUtils {
companion object {
const val PI = 3.14159
@JvmStatic
fun square(x: Int): Int = x * x
@JvmField
val TAG: String = "MathUtils"
}
}
// Java-ban MathUtils.square(5), MathUtils.TAG ként hívva
A @JvmStatic használata ajánlott minden olyan nyilvános companion object metódushoz, amelynek elérhetőnek kell lennie Java kódból. A const csak primitív típusokra és String-re alkalmazható — más típusokhoz használja a @JvmField annotációt.
Valós projektekben a companion object több standard forgatókönyvhöz használatos. Gyártó metódusok — a leggyakoribb minta: több különböző aláírású konstruktor helyett nevesített gyártó metódusokat használnak a companion object-ben.
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>()
A NetworkResult companion object-je biztosítja a loading() gyártó metódust, amely Loading példányt hoz létre a helyes generikus típussal. E metódus nélkül közvetlenül a Loading()-on keresztül kellene példányt létrehozni, ami felfedi a belső implementációt.
Gyakran a companion object az osztály-specifikus konstansok tárolására szolgál. A const val-lal deklarált konstansok fordítási időben beépülnek, ami nulla többletterhelést eredményez futásidőben.
class UserRepository {
companion object {
private const val TAG = "UserRepository"
private const val CACHE_SIZE = 100
private const val DEFAULT_PAGE_SIZE = 20
}
}
Gyakran Ismételt Kérdések
Az ordinary object — egy teljes jogú singleton, amely az osztálytól függetlenül létezik. companion object — egy object az osztályon belül, amelynek tagjai a külső osztály neve által hívhatók. Bájtkódban a companion object statikus beágyazott osztállyá, a szokásos object pedig autonóm singleton osztállyá válik.
Nem, a companion object nem öröklődik alosztályok által. Ha a B osztály örökli az A osztályt, a B.method() nem hívja meg az A osztály companion object-jének metódusát — az A.method()-on keresztül kell hivatkozni. Ez megfelel a statikus metódusok viselkedésének Java-ban.
Alapértelmezés szerint — a ClassName.Companion.method()-on keresztül. Statikus metódusként való híváshoz adjon @JvmStatic annotációt a companion object metódusához. Mezőkhöz használja a @JvmField-et vagy deklarálja őket const val-lal primitívek esetén.
A Kotlin fejlesztői a static elhagyása mellett döntöttek a companion object javára az egységes objektumkezelés érdekében. A static Java-ban megsérti az OOP elveit, mivel a statikus metódusok nem kapcsolódnak egy példányhoz. A companion object — elsőosztályú objektum, amely átadható, kiterjesztő függvényekkel bővíthető és interfészeket implementálhat.
A const val használatakor primitívek és String esetén — nulla többletterhelés, az érték beépül a bájtkódba. Metódusoknál nincs többletterhelés, ha a metódus nem inline. A legtöbb esetben a companion object-nek nincs mérhető hatása a teljesítményre. A @JvmStatic-et csak a Java-ból hívott nyilvános API-hoz használja.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is