métodos estáticos y variables en Kotlin?

3 minutos de lectura

Avatar de usuario de Caleb Bassham
Caleb Basham

Quiero poder guardar una instancia de clase en una variable estática privada/pública, pero no sé cómo hacerlo en Kotlin.

public class Foo {
    private static Foo instance;

    public Foo() {
        if (instance == null) {
            instance = this;
        }
    }
    
    public static Foo get() {
        return instance;
    }
}

Avatar de usuario de Eduard B.
eduardo b

Actualizar: Cualquiera (como OP) que solo necesite el llamado “Singleton”, a veces llamado “Servicio” (excepto en Android), simplemente debe usar el incorporado de Kotlin:

object Foo {
    // Done, this already does what OP needed,
    // because the boilerplate codes (like static field and constructor),
    // are taken care of by Kotlin.
}

(Como Roman señaló correctamente en la sección de comentarios).

Respuesta anterior; Si tiene (o planea tener) múltiples static variables, luego continúa leyendo:

Lo más parecido a los campos estáticos de Java es un objeto complementario. Puede encontrar la documentación de referencia para ellos aquí: https://kotlinlang.org/docs/reference/object-declarations.html#companion-objects

Su código en Kotlin se vería así:

class Foo {

    companion object {
        private lateinit var instance: Foo

        fun get(): Foo {
            return instance;
        }
    }

    init {
        if (instance == null) {
            instance = this
        }
    }

}

Si desea que sus campos/métodos se expongan como estáticos a las personas que llaman Java, puede aplicar el @JvmStatic anotación:

class Foo {

    companion object {
        private lateinit var instance: Foo

        @JvmStatic fun get(): Foo {
            return instance;
        }
    }

    init {
        if (instance == null) {
            instance = this
        }
    }

}

Nota eso @JvmStatic no necesita ninguna importación (ya que es una función integrada de Kotlin).

  • Si quieres usarlo como un static final campo en Java sin captadores, probablemente debería marcarlo @JvmField

    – artajerjes

    2 de mayo a las 7:22

Parece que desea definir un objeto singleton. Se admite en Kotlin como un concepto de primera clase:

object Foo {
  ... 
}

Kotlin se ocupa automáticamente de todo el código repetitivo con campo estático y constructor. No tienes que escribir nada de eso.

Desde el código de Kotlin, puede hacer referencia a la instancia de este objeto simplemente como Foo. Desde el código Java puede referirse a la instancia de este objeto como Foo.INSTANCEporque el compilador de Kotlin crea automáticamente el campo estático correspondiente denominado INSTANCE.

  • Esta es la solución mucho mejor, sin embargo, para mi caso de uso, necesitaba una clase porque necesitaba poder ser creada por un cargador de clases Java.

    – Caleb Basham

    26 de enero de 2020 a las 0:46

  • Sin embargo, se puede acceder a un objeto a lo largo de todo el proyecto, ¿no podría eso obstaculizar el rendimiento?

    – Arthur Kasparian

    12 ene a las 14:45

avatar de usuario de rakesh rajput
Rakesh Rajput

primero crea una clase simple y luego crea un bloque seguido de la palabra clave del objeto complementario

Por ejemplo:

class Test{

    companion object{

        fun  getValue(): String{

           return "Test String"

        }
    }
}

puede llamar a esta función de clase usando el nombre de la función de punto de nombre de clase

Por ejemplo:

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

avatar de usuario de jtonic
jtónico

Puede crear un objeto complementario para la clase y, si desea que el campo sea static puede usar la anotación @JvmStatic. El objeto complementario tiene acceso a miembros privados de la clase para la que es complementario.

Vea a continuación un ejemplo:

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

¿Ha sido útil esta solución?