Comportamiento de métodos estáticos en Kotlin

1. Información general

Una forma en la que el lenguaje Kotlin se diferencia de Java es que Kotlin no contiene la palabra clave estática con la que estamos familiarizados.

En este tutorial rápido, veremos algunas formas de lograr el comportamiento del método estático de Java en Kotlin.

2. Funciones a nivel de paquete

Comencemos por crear un archivo LoggingUtils.kt . Aquí, crearemos un método muy simple llamado debug . Como no nos importa mucho la funcionalidad dentro de nuestro método, solo imprimiremos un mensaje simple.

Dado que estamos definiendo nuestro método fuera de una clase, representa una función a nivel de paquete:

fun debug(debugMessage : String) { println("[DEBUG] $debugMessage") }

También veremos en el código descompilado que nuestro método de depuración ahora se declara como estático :

public final class LoggingUtilsKt { public static final void debug(@NotNull String debugMessage) { Intrinsics.checkParameterIsNotNull(debugMessage, "debugMessage"); String var1 = "[DEBUG] " + debugMessage; System.out.println(var1); } }

3. Objetos complementarios

Kotlin nos permite crear objetos que son comunes a todas las instancias de una clase: los objetos complementarios. Podemos crear una instancia singleton de un objeto simplemente agregando la palabra clave compañero .

Definamos nuestro método de depuración dentro de un objeto complementario :

class ConsoleUtils { companion object { fun debug(debugMessage : String) { println("[DEBUG] $debugMessage") } } }

Nuestro código descompilado nos muestra que podemos acceder al método de depuración a través del objeto Companion :

public final class ConsoleUtils { public static final ConsoleUtils.Companion Companion = new ConsoleUtils.Companion((DefaultConstructorMarker) null); public static final class Companion { public final void debug(@NotNull String debugMessage) { Intrinsics.checkParameterIsNotNull(debugMessage, "debugMessage"); String var2 = "[DEBUG] " + debugMessage; System.out.println(var2); } private Companion() {} public Companion(DefaultConstructorMarker $constructor_marker) { this(); } } }

Para evitar llamar a la instancia resultante con el nombre genérico Companion, también podemos darle un nombre personalizado.

Finalmente, para que el método de depuración vuelva a ser estático , debemos usar la anotación @JvmStatic :

class ConsoleUtils { companion object { @JvmStatic fun debug(debugMessage : String) { println("[DEBUG] $debugMessage") } } }

Al usarlo, terminaremos con un método de depuración de vacío final estático real en nuestro código descompilado:

public final class ConsoleUtils { public static final ConsoleUtils.Companion Companion = new ConsoleUtils.Companion((DefaultConstructorMarker) null); @JvmStatic public static final void debug(@NotNull String debugMessage) { Companion.debug(debugMessage); } public static final class Companion { @JvmStatic public final void debug(@NotNull String debugMessage) { Intrinsics.checkParameterIsNotNull(debugMessage, "debugMessage"); String var2 = "[DEBUG] " + debugMessage; System.out.println(var2); } private Companion() {} public Companion(DefaultConstructorMarker $constructor_marker) { this(); } } }

Ahora, podremos acceder a este nuevo método directamente a través de la clase ConsoleUtils .

4. Conclusión

En este breve tutorial, vimos cómo replicar en Kotlin el comportamiento de los métodos estáticos de Java . Hemos utilizado funciones a nivel de paquete y también objetos complementarios.

La implementación de todos estos fragmentos se puede encontrar en GitHub.