liveBook · Manning

Companion object

As explained in Kotlin in Action, 2E

A companion object is the specially designated object declaration inside a Kotlin class whose members can be accessed through the containing class name.

A companion object is an object declaration inside a Kotlin class whose members are reached through the class name. It provides class-related behavior without requiring a class instance: factory methods, shared properties, serialization logic, or other operations that need access to the class’s private internals. A class can have exactly one companion object. section 4.4.2 section 4.4.3

Call companion members through the class

Declare companion object inside a class, then call its members as MyClass.callMe(). Those members do not belong to MyClass instances, so MyClass().callMe() is unresolved. section 4.4.2

Companion objects are especially useful for named factory methods. A private constructor prevents unrestricted construction, while companion methods expose purpose-specific creation paths. Unlike several secondary constructors, factories can state why an object is being created, return a subclass, or avoid creating a new object when appropriate. section 4.4.2

Listing 4.33 Replacing secondary constructors with factory methods
class User private constructor(val nickname: String) {   #1
    companion object {                                   #2
        fun newSubscribingUser(email: String) =
            User(email.substringBefore('@'))
 
        fun newSocialUser(accountId: Int) =              #3
            User(getNameFromSocialNetwork(accountId))
    }
}

Compare overloaded secondary constructors with named factory methods held by a companion object. section 4.4.2

A companion object remains a regular object. It may have a name, implement an interface, and receive extension functions or properties. Kotlin normally lets callers omit its name: both Person.fromJSON(...) and Person.Loader.fromJSON(...) work for a named companion. An unnamed companion has the default name Companion. section 4.4.3

Use a class as an interface implementation

When a companion object implements JSONFactory<Person>, the class name can be passed where a JSONFactory<Person> is required: loadFromJSON(Person). This lets class-associated creation behavior satisfy an abstract factory interface. section 4.4.3

Companion objects often resemble Java static members at Kotlin call sites, but they are objects associated with a class rather than instance members. Kotlin uses the class name directly; Java accesses an unnamed companion through Person.Companion. Along with package-level declarations, companions replace many Java static methods and fields. section 4.4.2 section 4.4.3 section 4.6

Listing 4.36 Defining an extension function for a companion object
// business logic module
class Person(val firstName: String, val lastName: String) {
    companion object {                                       #1
    }
}
 
// client/server communication module
fun Person.Companion.fromJSON(json: String): Person {        #2
    /* ... */
}
 
val p = Person.fromJSON(json)

See how an extension on Person.Companion adds JSON construction outside the class while preserving Person.fromJSON(...) call syntax. section 4.4.3

How Kotlin in Action, 2E covers it

How deep it goes
Defines class-name access, private-constructor factories, naming, interface implementation, and extensions; defers generic details used by the factory example.
Examples
Demonstrates MyClass.callMe(), User creation factories, Person JSON loading, JSONFactory implementation, and a Person.Companion extension.
What it assumes
Builds from Kotlin classes and object declarations, while noting generics in the interface-factory example without developing them.
What you can do after
Apply it via Kotlin class declarations to expose factories, implement interfaces, and attach class-associated operations.
How it connects
Connects companion objects to factory methods, private constructors, object declarations, interfaces, extension functions, and package-level functions.

Also explained in

Compare how 2 books explain companion object →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.