Companion object in Kotlin: was es ist, Syntax und Verwendung

Autor: IT Sectr Veröffentlicht: 2026-06-21 Lesezeit: 9 Min.

companion object ist ein Mechanismus der Sprache Kotlin, der das Java-Schlüsselwort static für die Deklaration statischer Klassenmember ersetzt. Kotlin hat kein eingebautes static — stattdessen wird eine object-Deklaration mit dem Modifikator companion innerhalb einer Klasse verwendet. Laut JetBrains, 2025 erlaubt companion object, Methoden und Eigenschaften über den Klassennamen aufzurufen, was sie zum vollwertigen Äquivalent statischer Member im Java-Ökosystem macht.

Wichtige Punkte

  • companion object ist eine object-Deklaration innerhalb einer Klasse mit dem Schlüsselwort companion, die Java static ersetzt
  • Statische Member sind über den Klassennamen ohne Erstellung einer Instanz zugänglich: ClassName.method()
  • Benannter companion object erlaubt es, dem Objekt einen Namen für besser lesbaren Code zu geben
  • Schnittstellen in Kotlin können ebenfalls companion object mit Methodenimplementierungen enthalten
  • @JvmStatic — Annotation zum Exportieren von companion object-Methoden als echte static-Methoden in Java

Was ist companion object in Kotlin?

companion object ist eine besondere Art der object-Deklaration in Kotlin, die mit dem Schlüsselwort companion markiert wird. Sie erlaubt es, Member zu deklarieren, die zur Klasse und nicht zu ihren Instanzen gehören — also statische Member im Java-Sinne. Anders als in Java, wo static ein Modifikator für einzelne Felder und Methoden ist, werden in Kotlin statische Member innerhalb eines einzelnen Begleitobjekts gruppiert.

Jede Klasse in Kotlin kann genau ein companion object enthalten. Die Member dieses Objekts sind über den Klassennamen ohne Erstellung einer Instanz zugänglich: MyClass.method(). In Bytecode-Hinsicht wird ein companion object in eine separate innere Klasse kompiliert, und seine Methoden werden bei Verwendung der @JvmStatic-Annotation zu statischen Methoden der äußeren Klasse.

Laut Google I/O 2024 ist companion object zum Hauptmuster für Factory-Methoden, Konstanten und Hilfsfunktionen in modernen Android-Anwendungen in Kotlin geworden. Entwickler wählen es statt Utility-Klassen mit Paketlevel-Funktionen, da companion object eine logische Verbindung zur besitzenden Klasse beibehält.

Verwenden Sie companion object zum Gruppieren von statischem Kontext — Konstanten, Factorys, Hilfsmethoden, die logisch zur Klasse gehören, aber keine Instanz benötigen.

Companion object-Syntax: Deklaration und Zugriff

Die grundlegende Syntax von companion object ist einfach: Das Schlüsselwort companion wird vor die object-Deklaration innerhalb der Klasse gesetzt. Wenn kein Name angegeben wird, erhält das Objekt den Namen Companion, auf den explizit oder implizit zugegriffen werden kann.

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

// Access via class name
val table = User.TABLE_NAME
val user = User.create("Alice")

Im obigen Beispiel sind TABLE_NAME und create() über User.TABLE_NAME und User.create() zugänglich. Beachten Sie den const-Modifikator für primitive Konstanten — er garantiert die Inline-Setzung des Werts zur Kompilierzeit, ähnlich wie Java static final für primitive Typen und String.

Impliziter und expliziter Zugriff über Companion

Wenn ein companion object keinen Namen hat, kann über den automatischen Namen Companion: User.Companion.TABLE_NAME darauf zugegriffen werden. In der Praxis wird dies selten benötigt, ist aber beim Aufruf aus Java-Code oder bei Verwendung von Reflexion nützlich.

kotlin
// Both calls are equivalent
User.create("Bob")
User.Companion.create("Bob")

// Getting reference to companion object
val companion: User.Companion = User

Benannter companion object und Eigenschaften

Ein companion object kann einen Namen haben, was die Lesbarkeit des Codes verbessert und den Zugriff über einen aussagekräftigen Namen erlaubt. Factory ist der häufigste Name für ein als Factory verwendetes companion object.

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

// Access via Factory name
val response = HttpResponse.Factory.ok("data")

Ein benannter companion object hilft, den Zweck statischer Member zu dokumentieren. Bei der Refaktorierung macht der Name den Code selbstdokumentierend — der Entwickler sieht sofort, dass Factory Instanzen von HttpResponse erstellt.

Einschränkung: genau ein companion object pro Klasse

Eine Klasse kann nur ein companion object enthalten. Dies ist ein grundlegender Unterschied zu Java, wo Sie beliebig viele statische Felder und Methoden ohne Gruppierung deklarieren können. Wenn mehrere logische Gruppen statischer Member benötigt werden, verwenden Sie verschachtelte object-Deklarationen ohne companion.

Laut der offiziellen Kotlin-Dokumentation (Kotlin Docs, 2025) ist die Beschränkung auf ein companion object durch das Sprachdesign motiviert: Statische Member sollten eng mit der Klasse gekoppelt sein, und ein Begleitobjekt bietet eine klare Grenze für diese Verbindung. Wenn es zu viele statische Member gibt, ist dies ein Signal zur Refaktorierung der Klasse.

Companion object in Schnittstellen

In Kotlin können auch Schnittstellen ein companion object enthalten. Dies erlaubt es, statische Methoden und Konstanten direkt innerhalb einer Schnittstelle zu definieren, was in Java nicht möglich ist. Dieser Ansatz wird häufig zur Deklaration von Konstanten, die mit der Schnittstelle verbunden sind, oder von Factory-Methoden verwendet.

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

In diesem Beispiel gehören BASE_URL, TIMEOUT_MS und create() zur ApiService-Schnittstelle, nicht zu ihren Implementierungen. Dies ist praktisch: Alle Konstanten und die Factory-Logik zum Erstellen einer API-Dienstinstanz befinden sich an einem Ort — innerhalb der Schnittstelle selbst.

Implementierungen der Schnittstelle erben die Member des companion object nicht — sie werden nur über den Schnittstellennamen aufgerufen: ApiService.BASE_URL.

@JvmStatic und @JvmField: Java-Kompatibilität

Beim Aufruf von companion object-Methoden aus Java-Code sind sie standardmäßig als Methoden der verschachtelten Companion-Klasse zugänglich, nicht als statische Methoden der äußeren Klasse. Um sie als echte statische Methoden und Felder für Java zu exportieren, verwenden Sie die @JvmStatic-Annotation für Methoden und @JvmField für Felder.

AnnotationAnwendungErgebnis in Java
@JvmStaticCompanion object-MethodenStatische Methode: ClassName.method()
@JvmFieldCompanion object-FelderStatisches Feld: ClassName.field
constPrimitive Typen und StringInline-Konstante: Compiler ersetzt den Wert
ohne AnnotationMethoden/Felder standardmäßigCompanion.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"
    }
}

// Called in Java as MathUtils.square(5), MathUtils.TAG

Die Verwendung von @JvmStatic wird für alle öffentlichen companion object-Methoden empfohlen, die aus Java-Code zugänglich sein sollen. const wird nur auf primitive Typen und String angewendet — für andere Typen verwenden Sie @JvmField.

Praktische Beispiele zur Verwendung von companion object

In realen Projekten wird companion object für mehrere Standardszenarien verwendet. Factory-Methoden sind das häufigste Muster: Statt mehrerer Konstruktoren mit unterschiedlichen Signaturen werden benannte Factory-Methoden im companion object verwendet.

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 in NetworkResult bietet eine Factory-Methode loading(), die eine Loading-Instanz mit dem richtigen generischen Typ erstellt. Ohne diese Methode müsste man eine Instanz direkt über Loading() erstellen, was die interne Implementierung offenlegt.

Konstanten und Logging-Tags

companion object wird häufig zum Speichern klassen-spezifischer Konstanten verwendet. Mit const val deklarierte Konstanten werden zur Kompilierzeit inline gesetzt, was eine Null-Overhead zur Laufzeit bietet.

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

Häufig gestellte Fragen

Wie unterscheidet sich companion object von einem normalen object in Kotlin?

Ein normales object ist ein vollwertiges Singleton, das unabhängig von der Klasse existiert. companion object ist ein object innerhalb einer Klasse, dessen Member über den Namen der äußeren Klasse aufgerufen werden. Im Bytecode wird ein companion object zu einer statischen verschachtelten Klasse, während ein normales object zu einer autonomen Singleton-Klasse wird.

Kann companion object vererbt werden?

Nein, companion object wird nicht von Unterklassen geerbt. Wenn Klasse B von Klasse A erbt, ruft B.method() nicht die Methode aus dem companion object von Klasse A auf — Sie müssen A.method() aufrufen. Dies entspricht dem Verhalten statischer Methoden in Java.

Wie ruft man companion object aus Java-Code auf?

Standardmäßig — über ClassName.Companion.method(). Um es als statische Methode aufzurufen, fügen Sie @JvmStatic zur companion object-Methode hinzu. Für Felder verwenden Sie @JvmField oder deklarieren Sie sie mit const val für primitive Typen.

Warum gibt es kein static-Schlüsselwort in Kotlin?

Die Kotlin-Entwickler haben sich entschieden, static zugunsten von companion object aufzugeben, für eine einheitliche Arbeit mit Objekten. static in Java verstößt gegen OOP-Prinzipien, da statische Methoden nicht an eine Instanz gebunden sind. companion object ist ein erstklassiges Objekt, das übergeben, mit Erweiterungsfunktionen erweitert und Schnittstellen implementieren kann.

Beeinflusst companion object die Leistung?

Bei Verwendung von const val für primitive Typen und String — kein Overhead, der Wert wird in den Bytecode inline gesetzt. Bei Methoden gibt es keinen Overhead, es sei denn, die Methode ist inline. In den meisten Fällen erzeugt companion object keine messbaren Auswirkungen auf die Leistung. Verwenden Sie @JvmStatic nur für öffentliche APIs, die aus Java aufgerufen werden.

Zusammenfassung

  • companion object ist ein Kotlin-Mechanismus zur Deklaration statischer Klassenmember, der Java static ersetzt
  • Ein companion object pro Klasse — gruppiert alle statischen Elemente in einem Begleitobjekt
  • Zugriff über den Klassennamen: ClassName.method() oder ClassName.Companion.method()
  • @JvmStatic und @JvmField exportieren Member als echte statische Methoden und Felder für Java
  • const val für primitive Typen und String — setzt den Wert zur Kompilierzeit ohne Overhead inline
  • Schnittstellen unterstützen ebenfalls companion object für Konstanten und Factory-Methoden
  • Benannter companion object verbessert die Lesbarkeit des Codes und dokumentiert den Zweck statischer Member

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch