Недавно я столкнулся с вопросом во время проверки кода. Это было в контексте PR, где использовались kotlin class
и набор функций внутри сопутствующего объекта {}
, аннотированного как @JvmStatic
для взаимодействия с Java. Обратная связь была такой: “почему мы не можем преобразовать класс
в объект
и избавиться от сопутствующего объекта {}
?” .В связи с этим возник вопрос: "В чем польза от этого?"
. Было сделано некоторое объяснение, но я не был полностью удовлетворен данным объяснением (мной:)). Итак, решил немного почитать и задокументировать различия и варианты использования для моего дальнейшего использования и для тех, кто наткнется на подобный вопрос.
Объект
Объект
в kotlin – это способ реализации одиночных элементов
. Мы все сталкивались с необходимостью использования шаблона Singleton
в нашей карьере для различных вариантов использования. Что ж, в котлине это было сделано очень прямолинейно. напр.
object MyObject { // further implementation fun printHello() { println("Hello World!") } }
Эта реализация также называется объявление объекта
. Объявления объектов потокобезопасны и лениво инициализируются
, т.е. объекты инициализируются при первом обращении к ним.
Сопутствующий объект
Если мы хотим, чтобы какая-то реализация была классом
, но все еще хотим показать некоторое поведение как статическое
поведение , сопутствующий объект
приходите на спектакль. Это объявления объектов
внутри класса. Эти сопутствующие объекты инициализируются при разрешении содержащего класса, аналогично static
методы и переменные в мире java. напр.
class MyClass { // some implementations companion object { val SOME_STATIC_VARIABLE = "some_static_variable" fun someStaticFunction() { // static function implementation } } }
Резюме
Учитывая приведенное выше объяснение, вариант использования полностью зависит от проблемы, которую мы пытаемся решить. Если нам нужно обеспечить поведение Singleton
, то нам лучше использовать Objects
, иначе, если мы просто хотим добавить некоторую статическую сущность
в наши классы, мы можем использовать Сопутствующие объекты
.
Бонус – Доступ к объектам и компаньонам из Java
@JvmField
, lateinit
, const
, @JvmStatic
удобны, когда дело доходит до доступа к свойствам полей или функциям, определенным в objects
или сопутствующие объекты
. например, наш объект
может быть чем-то вроде приведенного ниже
object MyObject { @JvmStatic fun printStaticHello() { println("Static Hello World!") } fun printNonStaticHello() { println("Non-Static Hello World!") } }
Из Java
world мы можем получить доступ к этим функциям как:
MyObject.printStaticHello() OR MyObject.INSTANCE.printNonStaticHello() - this uses the singleton instance
например, доступ к сопутствующему объекту
class MyClass { companion object { @JvmStatic fun printStaticHello() { println("Static Hello World!") } fun printNonStaticHello() { println("Non-Static Hello World!") } } }
Из Java
world мы можем получить к ним доступ как:
MyClass.printStaticHello() MyClass.Companion.printStaticHello() MyClass.Companion.printNonStaticHello()
Спасибо вам за чтение. Примечание: Дальнейшее чтение и ссылки, здесь & здесь
Оригинал: “https://dev.to/bigyan4424/kotlin-object-vs-companion-object-1ohi”