Статичні методи і змінні Котліна


82

Я хочу мати можливість зберегти екземпляр класу у загальнодоступній статичній змінній, але я не можу зрозуміти, як це зробити в Kotlin.

class Foo {

    public static Foo instance;
    public Foo() {
        instance = this;
    }

}

7
kotlinlang.org/docs/reference/classes.html#companion-objects . Але це здається мені жахливим. Чому ви хочете використовувати змінне статичне поле (вже погана практика) і змінювати його кожного разу, коли створюєте екземпляр Foo? Чого ви намагаєтесь досягти?
JB Nizet,

3
Якщо ви хочете створити синглтон , перевірте kotlinlang.org/docs/reference/… .
Miha_x64

Відповіді:


124

Найближчим до статичних полів Java є об’єкт-супутник. Ви можете знайти посилання на документацію для них тут: https://kotlinlang.org/docs/reference/object-declarations.html#companion-objects

Ваш код у Kotlin буде виглядати приблизно так:

class Foo {

    companion object {
        lateinit var instance: Foo
    }

    init {
        instance = this
    }

}

Якщо ви хочете, щоб ваші поля / методи були виставлені статичними для абонентів Java, ви можете застосувати @JvmStaticанотацію:

class Foo {

    companion object {
        @JvmStatic lateinit var instance: Foo
    }

    init {
        instance = this
    }

}

12
Використання companion objectдля оголошення instanceполя - це шаблон, про який піклується компілятор Котліна автоматично, якщо ви просто заявляєте Fooякobject Foo { ... }
Роман Єлізаров

47

Схоже, ви хочете визначити одномісний об'єкт. Це підтримується в Kotlin як першокласна концепція:

object Foo {
  ... 
}

Весь шаблонний код зі статичним полем і конструктором автоматично переглядається Kotlin. Вам не потрібно писати нічого з цього.

З коду Kotlin ви можете посилатися на екземпляр цього об'єкта просто як Foo. З коду Java ви можете звернутися до екземпляра цього об'єкта як Foo.INSTANCE, оскільки компілятор Kotlin автоматично створює відповідне статичне поле з іменем INSTANCE.


Це набагато краще рішення, однак, для мого випадку використання мені потрібен клас, оскільки він повинен мати можливість створюватися завантажувачем класу Java.
Caleb Bassham

8

спочатку ви створюєте простий клас, після чого створюєте блок, за яким слідує ключове слово об’єкт-супутник

наприклад:

class Test{

    companion object{

        fun  getValue(): String{

           return "Test String"

        }
    }
}

Ви можете викликати цю функцію класу, використовуючи ім'я класу крапка ім'я функції

наприклад:

// here you will get the function value
Test.getValue() 

1

Ви можете створити супутній об’єкт для класу, і якщо ви хочете, щоб це поле було static ви можете використовувати анотацію @JvmStatic. Об'єкт-супутник має доступ до приватних членів класу, для якого він є супутником.

Дивіться нижче приклад:

class User {
    private lateinit var name: String

    override fun toString() = name

    companion object {
        @JvmStatic
        val instance by lazy {
            User().apply { name = "jtonic" }
        }
    }
}

class CompanionTest {

    @Test
    fun `test companion object`() {
        User.instance.toString() shouldBe "jtonic"
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.