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

