Компаньон-объект (companion object) в Kotlin — это объект, объявленный внутри класса с ключевым словом companion, позволяющий группировать статические методы и свойства, аналогично статическим членам в Java. В отличие от Java static, в Kotlin каждый компаньон-объект — полноценный объект, и на уровне байткода обращения к его членам компилируются как статические.
Companion.class MyFactory private constructor(val value: Int) { companion object { fun create(x: Int): MyFactory = MyFactory(x) } } val instance = MyFactory.create(10)
Почему не рекомендуется сохранять состояние (например, изменяемые переменные) внутри
companion objectв многопоточных приложениях?
Если разместить изменяемое состояние внутри companion object, оно становится разделяемым между всеми экземплярами класса и потоками, что приводит к race condition без дополнительной синхронизации.
class Counter { companion object { var count = 0 fun increment() { count++ } } } Counter.increment() // race condition при одновременных вызовах
История
На проекте Android разработчики сложили конфигурацию окружения внутрь
companion objectдля управления переключателем дебага. Это привело к путанице, когда разные фрагменты меняли одно и то же глобальное значение, возникло неожиданное поведение при асинхронных переходах.
История
На бекенде часть функционала была вынесена в
companion objectвместе с изменяемым кешем. При высокой нагрузке возникли ошибки и неконсистентное состояние данных из-за отсутствия синхронизации.
История
Начинающий разработчик пытался реализовать интерфейс только у компаньон-объекта, считая, что затем сможет использовать класс как этот интерфейс. В результате он столкнулся с невозможностью передать класс вместо компаньон-объекта, поскольку компаньон — это единственный объект, связанный с классом, а не сам класс.