Companion object i Kotlin: vad det är, syntax och tillämpning

Författare: IT Sectr Publicerad: 2026-06-21 Lästid: 9 min

companion object — mekanismen i Kotlin som ersätter nyckelordet static från Java för att deklarera statiska medlemmar i en klass. Kotlin har ingen inbyggd static — istället används en object-deklaration med modifieraren companion inuti klassen. Enligt JetBrains, 2025 gör companion object det möjligt att anropa metoder och egenskaper via klassnamnet, vilket gör dem till en fullständig motsvarighet till statiska medlemmar i Java-ekosystemet.

Huvudpunkter

  • companion object — en object-deklaration inuti klassen med nyckelordet companion, som ersätter Java static
  • Statiska medlemmar är tillgängliga via klassnamnet utan att skapa en instans: ClassName.method()
  • Namngivet companion object gör att objektet kan ges ett namn för mer läsbar kod
  • Gränssnitt i Kotlin kan också innehålla companion object med metodimplementationer
  • @JvmStatic — annotering för att exportera metoder från companion object som riktiga static-metoder i Java

Vad är companion object i Kotlin?

companion object — är en speciell typ av object declaration i Kotlin som markeras med nyckelordet companion. Den gör det möjligt att deklarera medlemmar som tillhör klassen, inte dess instanser — det vill säga statiska medlemmar i Java-terminologi. Till skillnad från Java där static är en modifierare för enskilda fält och metoder, grupperas i Kotlin statiska medlemmar inom ett enda följeobjekt.

Varje klass i Kotlin kan innehålla exakt ett companion object. Medlemmarna i detta objekt är tillgängliga via klassnamnet utan att skapa en instans: MyClass.method(). Samtidigt, ur bytekodsperspektiv, kompileras companion object till en separat inre klass och dess metoder blir statiska metoder i den yttre klassen när annoteringen @JvmStatic används.

Enligt Google I/O 2024 har companion object blivit det huvudsakliga mönstret för fabriksmetoder, konstanter och hjälpfunktioner i moderna Android-applikationer i Kotlin. Utvecklare väljer det framför hjälpklasser med paketfunktioner, eftersom companion object behåller den logiska kopplingen till ägarklassen.

Använd companion object för att gruppera statisk kontext — konstanter, fabriker, hjälpmetoder som logiskt hör till klassen men inte kräver någon instans.

Syntax för companion object: deklaration och åtkomst

Grundläggande syntax för companion object är enkel: nyckelordet companion placeras före object-deklarationen inuti klassen. Om inget namn anges får objektet namnet Companion, som man kan referera till explicit eller 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 }
}

// Åtkomst via klassnamn
val table = User.TABLE_NAME
val user = User.create("Alice")

I exemplet ovan är TABLE_NAME och create() tillgängliga via User.TABLE_NAME och User.create(). Observera modifieraren const för primitiva konstanter — den garanterar att värdet bäddas in vid kompilering, analogt med Java static final för primitiver och String.

Implicit och explicit åtkomst via Companion

Om companion object inte har något namn kan man komma åt det via det automatiska namnet Companion: User.Companion.TABLE_NAME. I praktiken behövs detta sällan, men det är användbart vid anrop från Java-kod eller vid användning av reflektion.

kotlin
// Båda anropen är likvärdiga
User.create("Bob")
User.Companion.create("Bob")

// Hämta referens till companion object
val companion: User.Companion = User

Namngivet companion object och egenskaper

Ett companion object kan ha ett namn, vilket förbättrar kodens läsbarhet och gör det möjligt att referera till det med ett begripligt namn. Factory — det vanligaste namnet för ett companion object som används som fabrik.

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")
    }
}

// Åtkomst via Factory-namn
val response = HttpResponse.Factory.ok("data")

Ett namngivet companion object hjälper till att dokumentera syftet med statiska medlemmar. Vid omfaktorisering gör namnet koden självdokumenterande — utvecklaren ser direkt att Factory skapar instanser av HttpResponse.

Begränsning: exakt ett companion object per klass

En klass kan bara innehålla ett companion object. Detta är en grundläggande skillnad från Java, där man kan deklarera hur många statiska fält och metoder som helst utan gruppering. Om flera logiska grupper av statiska medlemmar behövs, använd nästlade object-deklarationer utan companion.

Enligt den officiella Kotlin-dokumentationen (Kotlin Docs, 2025) motiveras begränsningen till ett companion object av språkets design: statiska medlemmar bör vara nära kopplade till klassen, och ett enda följeobjekt ger en tydlig gräns för denna koppling. Om det finns för många statiska medlemmar — är det en signal för omfaktorisering av klassen.

Companion object i gränssnitt

I Kotlin kan även gränssnitt innehålla ett companion object. Detta gör det möjligt att definiera statiska metoder och konstanter direkt inuti gränssnittet, vilket inte är möjligt i Java. Denna metod används ofta för att deklarera konstanter som är kopplade till gränssnittet eller fabriksmetoder.

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)
    }
}

I detta exempel tillhör BASE_URL, TIMEOUT_MS och create() gränssnittet ApiService, inte dess implementationer. Detta är bekvämt: alla konstanter och fabrikslogik för att skapa en instans av API-tjänsten finns på ett ställe — inuti själva gränssnittet.

Implementationer av gränssnittet ärver inte medlemmarna i companion object — de anropas endast via gränssnittets namn: ApiService.BASE_URL.

@JvmStatic och @JvmField: kompatibilitet med Java

När man anropar metoder från companion object i Java-kod är de som standard tillgängliga som metoder i den nästlade klassen Companion, inte som statiska metoder i den yttre klassen. För att exportera dem som riktiga static-metoder och -fält för Java, använd annoteringen @JvmStatic för metoder och @JvmField för fält.

AnnoteringAnvändningResultat i Java
@JvmStaticMetoder i companion objectStatisk metod: ClassName.method()
@JvmFieldFält i companion objectStatiskt fält: ClassName.field
constPrimitiver och StringInline-konstant: kompilatorn ersätter värdet
utan annoteringStandardmetoder/fältCompanion.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"
    }
}

// Anropas i Java som MathUtils.square(5), MathUtils.TAG

Användning av @JvmStatic rekommenderas för alla publika metoder i companion object som ska vara tillgängliga från Java-kod. const tillämpas endast på primitiva typer och String — för andra typer använd @JvmField.

Praktiska exempel på användning av companion object

I verkliga projekt används companion object för flera standardsituationer. Fabriksmetoder — det vanligaste mönstret: istället för flera konstruktorer med olika signaturer används namngivna fabriksmetoder i 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 i NetworkResult tillhandahåller fabriksmetoden loading() som skapar en Loading-instans med rätt generisk typ. Utan denna metod skulle man behöva skapa instansen direkt via Loading(), vilket avslöjar den interna implementationen.

Konstanter och taggar för loggning

Ofta används companion object för att lagra klasspecifika konstanter. Konstanter deklarerade med const val bäddas in vid kompilering, vilket ger noll overhead vid körning.

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

Vanliga frågor

Vad är skillnaden mellan companion object och ett vanligt object i Kotlin?

Ett ordinary object — är en fullvärdig singleton som existerar oberoende av klassen. companion object — är ett object inuti klassen vars medlemmar anropas via den yttre klassens namn. I bytekod blir companion object en statisk nästlad klass, medan ett vanligt object blir en autonom singleton-klass.

Kan companion object ärvas?

Nej, companion object ärvs inte av underklasser. Om klass B ärver klass A kommer B.method() inte att anropa en metod från klass A:s companion object — man måste gå via A.method(). Detta motsvarar beteendet hos statiska metoder i Java.

Hur anropar man companion object från Java-kod?

Som standard — via ClassName.Companion.method(). För att anropa som en statisk metod, lägg till @JvmStatic till metoden i companion object. För fält, använd @JvmField eller deklarera dem med const val för primitiver.

Varför har Kotlin inget static-nyckelord?

Kotlins utvecklare bestämde sig för att överge static till förmån för companion object för enhetlig hantering av objekt. Static i Java bryter mot OOP-principerna eftersom statiska metoder inte är bundna till en instans. Ett companion object — är ett förstklassigt objekt som kan skickas runt, utökas med tilläggsfunktioner och implementera gränssnitt.

Påverkar companion object prestandan?

Vid användning av const val för primitiver och String — noll overhead, värdet bäddas in i bytekoden. För metoder finns det ingen overhead om metoden inte är inline. I de flesta fall har companion object ingen mätbar påverkan på prestandan. Använd @JvmStatic endast för publikt API som anropas från Java.

Sammanfattning

  • companion object — Kotlin-mekanism för att deklarera statiska klassmedlemmar, ersätter Java static
  • Ett companion object per klass — grupperar alla statiska element i ett följeobjekt
  • Åtkomst via klassnamnet: ClassName.method() eller ClassName.Companion.method()
  • @JvmStatic och @JvmField exporterar medlemmar som riktiga statiska metoder och fält för Java
  • const val för primitiver och String — bäddar in värdet vid kompilering utan overhead
  • Gränssnitt stöder också companion object för konstanter och fabriksmetoder
  • Namngivet companion object förbättrar kodläsbarhet och självdokumenterar syftet med statiska medlemmar

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också