A companion object (companion object) in Kotlin is an object declared inside a class with the keyword companion, allowing for the grouping of static methods and properties, similar to static members in Java. Unlike Java static members, every companion object in Kotlin is a full-fledged object, and at the bytecode level, access to its members is compiled as static calls.
Companion.class MyFactory private constructor(val value: Int) { companion object { fun create(x: Int): MyFactory = MyFactory(x) } } val instance = MyFactory.create(10)
Why is it not recommended to store state (for example, mutable variables) inside a
companion objectin multithreaded applications?
If mutable state is placed inside a companion object, it becomes shared among all instances of the class and threads, leading to race conditions without additional synchronization.
class Counter { companion object { var count = 0 fun increment() { count++ } } } Counter.increment() // race condition on simultaneous calls
Story
In an Android project, developers placed the environment configuration inside a
companion objectto manage the debug switch. This led to confusion when different fragments changed the same global value, resulting in unexpected behavior during asynchronous transitions.
Story
In the backend, part of the functionality was moved to a
companion objectalong with a mutable cache. Under high load, errors and inconsistent data state arose due to the lack of synchronization.
Story
A beginner developer tried to implement an interface only in the companion object, thinking that they could then use the class as this interface. As a result, they faced the inability to pass the class instead of the companion object, as the companion is the only object associated with the class, not the class itself.