Что такое companion objects в Kotlin
Что проверяют
Понимаете ли вы, что это объект, а не статический блок, и знаете ли следствия этого различия.
Как отвечать
В Kotlin нет статических членов. Их роль играет объект-компаньон: единственный экземпляр, привязанный к классу и создаваемый при первом обращении.
class User(val id: String) {
companion object {
const val TABLE = "users"
fun fromRow(row: Row) = User(row["id"])
}
}
User.fromRow(row) // вызов выглядит как статическийКлючевое отличие от статики: компаньон это настоящий объект, поэтому он может реализовывать интерфейсы, наследоваться, быть получателем расширений и передаваться как значение через User.Companion. Статический метод Java так не умеет.
Практические детали:
- имя необязательно, по умолчанию
Companion; const valпревращается в настоящую константу времени компиляции, а обычноеvalв компаньоне это свойство с геттером;@JvmStaticнужен, чтобы из Java вызов выглядел статическим, иначе придётся писатьUser.Companion.fromRow(...);- фабричные методы это основной сценарий: приватный конструктор плюс
createв компаньоне; - у компаньона есть доступ к приватным членам класса.
Отдельно стоит сказать про частую ошибку: компаньон живёт столько же, сколько класс, то есть фактически всё время работы приложения. Ссылка на контекст активности или на большой объект в нём это утечка.
Где спотыкаются
Считают компаньон полным аналогом static.
Держат в нём изменяемое состояние и получают глобальную переменную со всеми её проблемами.
Не знают про @JvmStatic и удивляются неудобному вызову из Java.
Путают компаньон и object: второй это одиночка сам по себе, не привязанный к классу.