Котлинский объект против объекта-компаньона
Недавно я столкнулся с вопросом во время проверки кода. Это было в контексте PR, где использовались kotlin class
и куча функций внутри companion object {}
, помеченных как @JvmStatic
для взаимодействия с Java. Ответ был таким: «Почему мы не можем преобразовать class
в object
и избавиться от _6 _?» Это вызвало вопрос "what is the benefit with that?"
. Было дано какое-то объяснение, но я не был полностью удовлетворен данным объяснением (мной :)). Итак, я решил немного почитать и задокументировать различия и варианты использования для моей будущей справки и для тех, кто наткнется на аналогичный вопрос.
Объект
Object
в котлине - это способ реализации Singletons
. Все мы сталкивались с необходимостью Singleton
шаблона в нашей карьере для различных сценариев использования. Что ж, в котлине это сделано очень просто.
например
Эта реализация также называется object declaration
. Объявления объектов являются потокобезопасными и lazy initialized
, т.е. объекты инициализируются при первом доступе к ним.
Сопутствующий объект
Если мы хотим, чтобы какая-то реализация была class
, но все же хотим показать какое-то поведение как static
поведение, companion object
вступаем в игру. Это object declarations
внутри класса. Эти сопутствующие объекты инициализируются при разрешении содержащего класса, аналогично static
методам и переменным в мире Java.
например.
Резюме
Учитывая приведенное выше объяснение, вариант использования полностью зависит от проблемы, которую мы пытаемся решить. Если нам нужно обеспечить поведение Singleton
, тогда нам будет лучше с Objects
, иначе, если мы просто хотим добавить немного static essence
в наши классы, мы можем использовать Companion objects
.
Бонус - доступ к объектам и компаньонам из Java
@JvmField
, lateinit
, const
, @JvmStatic
удобны, когда дело доходит до доступа к свойствам поля или функциям, определенным в objects
или companion objects
.
например наш object
может быть примерно таким, как показано ниже
Из Java
мира мы можем получить доступ к этим функциям как:
MyObject.printStaticHello() OR MyObject.INSTANCE.printNonStaticHello() - this uses the singleton instance
Доступ к companion object
Из Java
мира мы можем получить к ним доступ как:
MyClass.printStaticHello()
MyClass.Companion.printStaticHello() MyClass.Companion.printNonStaticHello()
Спасибо за чтение.
Примечание. Дополнительная литература и ссылки, здесь и здесь
Первоначально опубликовано на https://dev.to 9 марта 2020 г.