¿Es posible acceder a las funciones de extensión desde el código Java?
Definí la función de extensión en un archivo Kotlin.
package com.test.extensions
import com.test.model.MyModel
/**
*
*/
public fun MyModel.bar(): Int {
return this.name.length()
}
Donde MyModel
es una clase Java (generada). Ahora, quería acceder a él en mi código normal de Java:
MyModel model = new MyModel();
model.bar();
Sin embargo, eso no funciona. El IDE no reconocerá el bar()
método y la compilación falla.
Lo que sí funciona es usar una función estática de kotlin:
public fun bar(): Int {
return 2*2
}
mediante el uso de import com.test.extensions.ExtensionsPackage
modo que mi IDE parece estar configurado correctamente.
Busqué en todo el archivo de interoperabilidad Java de los documentos de Kotlin y también busqué mucho en Google, pero no pude encontrarlo.
¿Qué estoy haciendo mal? ¿Es esto posible?
java
kotlin
extension-function
Lovis
fuente
fuente
import package com.test.extensions.MyModel
¿ Tú también ?com.test.extensions.ExtensionsPackage
Respuestas:
Todas las funciones de Kotlin declaradas en un archivo se compilarán por defecto a métodos estáticos en una clase dentro del mismo paquete y con un nombre derivado del archivo fuente de Kotlin (Primera letra en mayúscula y extensión ".kt" reemplazada por el sufijo "Kt" ) . Los métodos generados para las funciones de extensión tendrán un primer parámetro adicional con el tipo de receptor de función de extensión.
Al aplicarlo a la pregunta original, el compilador de Java verá el archivo fuente de Kotlin con el nombre example.kt
como si la siguiente clase Java fuera declarada
Como no sucede nada con la clase extendida desde el punto de vista de Java, no puede simplemente usar la sintaxis de puntos para acceder a dichos métodos. Pero todavía son invocables como métodos estáticos normales de Java:
La importación estática se puede usar para la clase ExampleKt:
fuente
bar(model, param1, param2);
La función de extensión de nivel superior de Kotlin se compila como métodos estáticos de Java.
Dado el archivo Kotlin
Extensions.kt
en el paquete quefoo.bar
contiene:El código Java equivalente sería:
A menos que, es decir,
Extensions.kt
contenga la líneaEn cuyo caso la clase estática de Java se llamaría
DemoUtils
En Kotlin, los métodos de extensión se pueden declarar de otras maneras. (Por ejemplo, como una función miembro o como una extensión de un objeto complementario).
fuente
Tengo un archivo Kotlin llamado NumberFormatting.kt que tiene la siguiente función
En java, simplemente accedo a él sobre el archivo NumberFormattingKt de la siguiente manera después de la importación requerida
import ....extensions.NumberFormattingKt;
fuente
Siempre puede ver el código Java real que se genera a partir de su código Kotlin yendo a
Tools > Kotlin > Show Kotlin Bytecode
, luego haciendo clicDecompile
. Esto puede ayudarte tremendamente. En su caso, el código Java se verá así si tieneMyModelExtensions.kt
puede mejorar esto usando
@JvmName
el archivo que contienebar
:y dará como resultado este código:
El uso
MyModels
está en línea con lo que sugiere Java Efectivo para las clases de utilidad. También puede cambiar el nombre de su método de esta manera:entonces desde el lado de Java parecerá idiomático:
fuente
Necesita duplicar sus funciones en los archivos de clase:
Crear archivo Kotlin, por ejemplo, Utils.kt
Inserte el código
O
En el uso de kotlin:
En Java use esto:
fuente
Esto funciona para mi:
Kotlin
Código Java
Mi proyecto es un antiguo proyecto de Android creado con Java; ahora creé el primer archivo kotlin y agregué extensiones de String fun String.isNotNullOrEmpty (): Boolean {...}
y podría llamarlo desde un archivo java usando: StringUtilsKt.isNotNullOrEmpty (thestring).
Mi nombre de archivo kotlin es StringUtils
fuente
Las otras respuestas aquí cubren el caso de llamar a una función de extensión ubicada en el nivel superior de un archivo de paquete Kotlin.
Sin embargo, mi caso fue que necesitaba llamar a una función de Extensión ubicada dentro de una Clase. Específicamente, estaba tratando con un Objeto.
La solución es increíblemente simple .
¡Todo lo que tiene que hacer es anotar su función de extensión como
@JvmStatic
, y listo! Su código Java podrá acceder a él y usarlo.fuente
Cuando extiendes una clase como esta:
Se compilará para esto:
Hay más ejemplos aquí .
fuente
Por lo que puedo decir, esto no es posible. De mi lectura de los documentos de extensiones, parece que
crea un nuevo método con la firma
Luego, Kotlin asigna esa función a las llamadas del formulario
myModel.bar()
, donde sibar()
no se encuentra en laMyModel
clase, busca métodos estáticos que coincidan con la firma y el esquema de nombres que genera.Tenga en cuenta que esto es solo una suposición de sus declaraciones sobre extensiones que se importan estáticamente y que no anulan los métodos definidos. No he llegado lo suficientemente lejos en su fuente para saber con certeza.Por lo tanto, suponiendo que lo anterior es cierto, no hay forma de que las extensiones de Kotlin se invoquen desde un código java antiguo, ya que el compilador solo verá un método desconocido que se llama en un objeto y se produce un error.
fuente