Kotlin statische Methoden und Variablen

78

Ich möchte eine Klasseninstanz in einer öffentlichen statischen Variablen speichern können, kann aber nicht herausfinden, wie dies in Kotlin gemacht wird.

class Foo {

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

}
Caleb Bassham
quelle
7
kotlinlang.org/docs/reference/classes.html#companion-objects . Aber das sieht für mich schrecklich aus. Warum möchten Sie ein veränderbares statisches Feld verwenden (bereits schlechte Praxis) und es jedes Mal ändern, wenn Sie eine Instanz von Foo erstellen? Was versuchst du zu erreichen?
JB Nizet
3
Wenn Sie einen Singleton erstellen möchten, besuchen Sie kotlinlang.org/docs/reference/… .
Miha_x64

Antworten:

121

Das, was Javas statischen Feldern am nächsten kommt, ist ein Begleitobjekt. Die Dokumentationsreferenz für sie finden Sie hier: https://kotlinlang.org/docs/reference/object-declarations.html#companion-objects

Ihr Code in Kotlin würde ungefähr so ​​aussehen:

class Foo {

    companion object {
        lateinit var instance: Foo
    }

    init {
        instance = this
    }

}

Wenn Sie möchten, dass Ihre Felder / Methoden für Java-Aufrufer als statisch angezeigt werden, können Sie die @JvmStaticAnmerkung anwenden :

class Foo {

    companion object {
        @JvmStatic lateinit var instance: Foo
    }

    init {
        instance = this
    }

}
Eduard B.
quelle
12
Die Verwendung von companion object, um ein instanceFeld zu deklarieren , ist eine Boilerplate, die vom Kotlin-Compiler automatisch Fooobject Foo { ... }
erledigt wird,
47

Es sieht so aus, als ob Sie ein Singleton-Objekt definieren möchten. Es wird in Kotlin als erstklassiges Konzept unterstützt:

object Foo {
  ... 
}

Der gesamte Boilerplate-Code mit statischem Feld und Konstruktor wird vom Kotlin automatisch übernommen. Sie müssen nichts davon schreiben.

Aus dem Kotlin-Code können Sie auf die Instanz dieses Objekts einfach als verweisen Foo. Aus dem Java-Code können Sie auf die Instanz dieses Objekts als verweisen Foo.INSTANCE, da der Kotlin-Compiler automatisch das entsprechende statische Feld mit dem Namen erstellt INSTANCE.

Roman Elizarov
quelle
Dies ist die viel bessere Lösung. Für meinen Anwendungsfall benötigte ich jedoch eine Klasse, da diese von einem Java-Klassenladeprogramm erstellt werden konnte.
Caleb Bassham
8

Zuerst erstellen Sie eine einfache Klasse, dann erstellen Sie einen Block, gefolgt von einem Schlüsselwort für das Begleitobjekt

zum Beispiel:

class Test{

    companion object{

        fun  getValue(): String{

           return "Test String"

        }
    }
}

Sie können diese Klassenfunktion mit dem Klassennamen dot function name aufrufen

zum Beispiel:

// here you will get the function value
Test.getValue() 
Rakesh Rajput
quelle
1

Sie können ein Begleitobjekt für die Klasse erstellen. Wenn das Feld staticangezeigt werden soll , können Sie die Annotation @JvmStatic verwenden. Companion-Objekte haben Zugriff auf private Mitglieder der Klasse, für die es Companion ist.

Siehe unten ein Beispiel:

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"
    }
}
jtonic
quelle