Ist es möglich, über Java-Code auf Erweiterungsfunktionen zuzugreifen?
Ich habe die Erweiterungsfunktion in einer Kotlin-Datei definiert.
package com.test.extensions
import com.test.model.MyModel
/**
*
*/
public fun MyModel.bar(): Int {
return this.name.length()
}
Wo MyModel
ist eine (generierte) Java-Klasse? Jetzt wollte ich in meinem normalen Java-Code darauf zugreifen:
MyModel model = new MyModel();
model.bar();
Das funktioniert jedoch nicht. Die IDE erkennt die bar()
Methode nicht und die Kompilierung schlägt fehl.
Was funktioniert, ist die Verwendung einer statischen Funktion von kotlin:
public fun bar(): Int {
return 2*2
}
durch die Verwendung import com.test.extensions.ExtensionsPackage
so scheint mein IDE korrekt konfiguriert werden.
Ich habe die gesamte Java-Interop-Datei aus den Kotlin-Dokumenten durchsucht und auch viel gegoogelt, aber ich konnte sie nicht finden.
Was mache ich falsch? Ist das überhaupt möglich?
java
kotlin
extension-function
Lovis
quelle
quelle
import package com.test.extensions.MyModel
?com.test.extensions.ExtensionsPackage
Antworten:
Alle in einer Datei deklarierten Kotlin-Funktionen werden standardmäßig zu statischen Methoden in einer Klasse innerhalb desselben Pakets und mit einem Namen kompiliert, der von der Kotlin-Quelldatei abgeleitet ist (Großbuchstabe groß geschrieben und Erweiterung ".kt" durch das Suffix "Kt" ersetzt ). . Für Erweiterungsfunktionen generierte Methoden haben einen zusätzlichen ersten Parameter mit dem Empfängertyp der Erweiterungsfunktion.
Wenn der Java-Compiler es auf die ursprüngliche Frage anwendet, wird die Kotlin-Quelldatei mit dem Namen example.kt angezeigt
als ob die folgende Java-Klasse deklariert wäre
Da aus Java-Sicht mit der erweiterten Klasse nichts passiert, können Sie nicht einfach die Punktsyntax verwenden, um auf solche Methoden zuzugreifen. Sie können jedoch weiterhin als normale statische Java-Methoden aufgerufen werden:
Der statische Import kann für die ExampleKt-Klasse verwendet werden:
quelle
bar(model, param1, param2);
Kotlin-Erweiterungsfunktionen der obersten Ebene werden als statische Java-Methoden kompiliert.
Gegebene Kotlin-Datei
Extensions.kt
in Paketfoo.bar
mit:Der entsprechende Java-Code wäre:
Es sei denn, das heißt,
Extensions.kt
die Zeile enthaltenIn diesem Fall würde die statische Java-Klasse benannt
DemoUtils
In Kotlin können Erweiterungsmethoden auf andere Weise deklariert werden. (Zum Beispiel als Elementfunktion oder als Erweiterung eines Begleitobjekts.)
quelle
Ich habe eine Kotlin-Datei namens NumberFormatting.kt, die die folgende Funktion hat
In Java greife ich nach dem erforderlichen Import einfach über die Datei NumberFormattingKt wie folgt darauf zu
import ....extensions.NumberFormattingKt;
quelle
Sie können immer den tatsächlichen Java-Code sehen, der aus Ihrem Kotlin-Code generiert wird, indem Sie auf
Tools > Kotlin > Show Kotlin Bytecode
klicken und dann auf klickenDecompile
. Dies kann Ihnen enorm helfen. In Ihrem Fall sieht der Java-Code folgendermaßen ausMyModelExtensions.kt
Sie können dies verbessern, indem Sie
@JvmName
für die Datei Folgendes verwendenbar
:und es wird zu diesem Code führen:
Die Verwendung entspricht den
MyModels
Vorschlägen von Effective Java für Dienstprogrammklassen. Sie können Ihre Methode auch folgendermaßen umbenennen:dann wird es von der Java-Seite idiomatisch aussehen:
quelle
Sie müssen Ihre Funktionen in den Klassendateien duplizieren:
Erstellen Sie eine Kotlin-Datei, z. B. Utils.kt
Gib den code ein
ODER
In Kotlin verwenden:
Verwenden Sie in Java Folgendes:
quelle
Für mich geht das:
Kotlin
Java-Code
Mein Projekt ist ein altes Android-Projekt, das mit Java erstellt wurde. Jetzt habe ich die erste Kotlin-Datei erstellt und String-Erweiterungen hinzugefügt. fun String.isNotNullOrEmpty (): Boolean {...}
und ich könnte es aus der Java-Datei aufrufen, indem ich: StringUtilsKt.isNotNullOrEmpty (thestring).
Mein Kotlin-Dateiname ist StringUtils
quelle
Die anderen Antworten hier beziehen sich auf den Fall des Aufrufs einer Erweiterungsfunktion, die sich auf der obersten Ebene einer Kotlin-Paketdatei befindet.
Mein Fall war jedoch, dass ich eine Erweiterungsfunktion innerhalb einer Klasse aufrufen musste. Insbesondere habe ich mich mit einem Objekt befasst.
Die Lösung ist unglaublich einfach .
Alles was Sie tun müssen, ist Ihre Erweiterungsfunktion als
@JvmStatic
und voila zu kommentieren! Ihr Java-Code kann darauf zugreifen und ihn verwenden.quelle
Wenn Sie eine Klasse wie diese erweitern:
Es wird dazu kompiliert:
Hier finden Sie weitere Beispiele .
quelle
Soweit ich das beurteilen kann, ist dies nicht möglich. Aus meiner Lektüre der Erweiterungsdokumente geht hervor, dass
erstellt eine neue Methode mit der Signatur
Dann ordnet Kotlin diese Funktion Aufrufen des Formulars zu
myModel.bar()
. Wennbar()
sie in derMyModel
Klasse nicht gefunden werden , sucht sie nach statischen Methoden, die mit dem ausgegebenen Signatur- und Namensschema übereinstimmen. Beachten Sie, dass dies nur eine Annahme aus ihren Aussagen über statisch importierte Erweiterungen ist, die definierte Methoden nicht überschreiben. Ich bin in ihrer Quelle nicht weit genug gekommen, um es sicher zu wissen.Unter der Annahme, dass das oben Gesagte zutrifft, können Kotlin-Erweiterungen nicht aus einfachem alten Java-Code aufgerufen werden, da der Compiler nur eine unbekannte Methode für ein Objekt aufruft und einen Fehler ausgibt.
quelle