Est-il possible d'accéder aux fonctions d'extension à partir du code Java?
J'ai défini la fonction d'extension dans un fichier Kotlin.
package com.test.extensions
import com.test.model.MyModel
/**
*
*/
public fun MyModel.bar(): Int {
return this.name.length()
}
Où MyModel
est une classe java (générée). Maintenant, je voulais y accéder dans mon code java normal:
MyModel model = new MyModel();
model.bar();
Cependant, cela ne fonctionne pas. L'EDI ne reconnaîtra pas la bar()
méthode et la compilation échoue.
Ce qui fonctionne est d'utiliser avec une fonction statique de kotlin:
public fun bar(): Int {
return 2*2
}
en utilisant import com.test.extensions.ExtensionsPackage
donc mon IDE semble être configuré correctement.
J'ai cherché dans tout le fichier Java-interop à partir de la documentation kotlin et j'ai beaucoup cherché sur Google, mais je ne l'ai pas trouvé.
Qu'est-ce que je fais mal? Est-ce seulement possible?
import package com.test.extensions.MyModel
?com.test.extensions.ExtensionsPackage
Réponses:
Toutes les fonctions Kotlin déclarées dans un fichier seront compilées par défaut en méthodes statiques dans une classe du même package et avec un nom dérivé du fichier source Kotlin (première lettre en majuscule et extension ".kt" remplacée par le suffixe "Kt" ) . Les méthodes générées pour les fonctions d'extension auront un premier paramètre supplémentaire avec le type de récepteur de fonction d'extension.
En l'appliquant à la question d'origine, le compilateur Java verra le fichier source Kotlin avec le nom example.kt
comme si la classe Java suivante était déclarée
Comme rien ne se passe avec la classe étendue du point de vue Java, vous ne pouvez pas simplement utiliser la syntaxe à points pour accéder à ces méthodes. Mais ils sont toujours appelables en tant que méthodes statiques Java normales:
L'importation statique peut être utilisée pour la classe ExampleKt:
la source
bar(model, param1, param2);
Les fonctions d'extension de niveau supérieur Kotlin sont compilées en tant que méthodes statiques Java.
Compte tenu du fichier Kotlin
Extensions.kt
dans le packagefoo.bar
contenant:Le code Java équivalent serait:
Sauf si, c'est-à-dire
Extensions.kt
contenait la ligneDans ce cas, la classe statique Java serait nommée
DemoUtils
Dans Kotlin, les méthodes d'extension peuvent être déclarées de différentes manières. (Par exemple, en tant que fonction membre ou en tant qu'extension d'un objet compagnon.)
la source
J'ai un fichier Kotlin appelé NumberFormatting.kt qui a la fonction suivante
En java, j'y accède simplement via le fichier NumberFormattingKt de la manière suivante après l'importation requise
import ....extensions.NumberFormattingKt;
la source
Vous pouvez toujours voir le code Java réel généré à partir de votre code Kotlin en accédant à
Tools > Kotlin > Show Kotlin Bytecode
, puis en cliquant surDecompile
. Cela peut vous aider énormément. Dans votre cas, le code Java ressemblera à ceci si vous avezMyModelExtensions.kt
vous pouvez améliorer cela en utilisant
@JvmName
le fichier contenantbar
:et il en résultera ce code:
L'utilisation
MyModels
est conforme à ce que suggère Effective Java pour les classes d'utilitaires. Vous pouvez également renommer votre méthode comme ceci:puis du côté Java, cela aura l'air idiomatique:
la source
Vous devez dupliquer vos fonctions dans les fichiers de classe:
Créer un fichier Kotlin, par exemple Utils.kt
Entrer le code
OU
Dans kotlin, utilisez:
En Java, utilisez ceci:
la source
Ça marche pour moi:
Kotlin
Code Java
Mon projet est un ancien projet Android créé avec Java; maintenant j'ai créé le premier fichier kotlin et ajouté des extensions de chaîne amusantes String.isNotNullOrEmpty (): Boolean {...}
et je pourrais l'appeler à partir du fichier java en utilisant: StringUtilsKt.isNotNullOrEmpty (thestring).
Le nom de mon fichier kotlin est StringUtils
la source
Les autres réponses ici couvrent le cas de l'appel d'une fonction d'extension située au niveau supérieur d'un fichier de package Kotlin.
Cependant, mon cas était que je devais appeler une fonction d'extension située à l'intérieur d'une classe. Plus précisément, j'avais affaire à un objet.
La solution est incroyablement simple .
Tout ce que vous avez à faire est d'annoter votre fonction d'extension comme
@JvmStatic
, et le tour est joué! Votre code Java pourra y accéder et l'utiliser.la source
Lorsque vous étendez une classe comme celle-ci:
Il compilera à ceci:
Il y a plus d' exemples ici .
la source
Autant que je sache, ce n'est pas possible. D'après ma lecture de la documentation sur les extensions, il semble que
crée une nouvelle méthode avec la signature
Ensuite, Kotlin mappe cette fonction aux appels du formulaire
myModel.bar()
, où s'ilbar()
n'est pas trouvé dans laMyModel
classe, il recherche les méthodes statiques correspondant à la signature et au schéma de dénomination qu'il génère. Notez que ce n'est qu'une hypothèse de leurs déclarations sur les extensions importées statiquement et non sur les méthodes définies. Je ne suis pas allé assez loin dans leur source pour en être sûr.Donc, en supposant que ce qui précède est vrai, il n'y a aucun moyen pour les extensions Kotlin d'être appelées à partir de l'ancien code java, car le compilateur verra simplement une méthode inconnue appelée sur un objet et une erreur.
la source