是否可以从Java代码访问扩展函数?
我在Kotlin文件中定义了扩展函数。
package com.test.extensions
import com.test.model.MyModel
/**
*
*/
public fun MyModel.bar(): Int {
return this.name.length()
}
其中MyModel是一个(生成的)java类。
现在,我想在我的正常java代码中访问它:
MyModel model = new MyModel();
model.bar();
然而,这并不奏效。IDE无法识别bar()方法,编译失败。
有效的方法是使用kotlin中的静态函数:
public fun bar(): Int {
return 2*2
}
通过使用import com.test.extensions.ExtensionsPackage,这样我的IDE似乎配置正确。
我从kotlin文档中搜索了整个Java-interop文件,也搜索了很多,但我没有找到它。
我做错了什么?这可能吗?
当你像这样扩展一个类时:
fun String.concatenatedLength(str: String): Int {
return (this.length + str.length)
}
fun f() {
var len = "one string".concatenatedLength("another string")
println(len)
}
它将编译为:
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
public final class ExampleKt {
public static final int concatenatedLength(@NotNull String $receiver, @NotNull String str) {
Intrinsics.checkParameterIsNotNull((Object) $receiver, (String) "$receiver");
Intrinsics.checkParameterIsNotNull((Object) str, (String) "str");
return $receiver.length() + str.length();
}
public static final void f() {
int len = ExampleKt.concatenatedLength("one string", "another string");
System.out.println(len);
}
}
这里还有更多的例子。
Kotlin顶级扩展函数被编译为Java静态方法。
给定Kotlin文件扩展名。foo中的Kt。栏包含:
fun String.bar(): Int {
...
}
等价的Java代码是:
package foo.bar;
class ExtensionsKt {
public static int bar(String receiver) {
...
}
}
除非,也就是说,扩展。Kt包含这条线
@file:JvmName("DemoUtils")
在这种情况下,Java静态类将被命名为DemoUtils
在Kotlin中,扩展方法可以用其他方式声明。(例如,作为成员函数或作为伴生对象的扩展。)
当你像这样扩展一个类时:
fun String.concatenatedLength(str: String): Int {
return (this.length + str.length)
}
fun f() {
var len = "one string".concatenatedLength("another string")
println(len)
}
它将编译为:
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
public final class ExampleKt {
public static final int concatenatedLength(@NotNull String $receiver, @NotNull String str) {
Intrinsics.checkParameterIsNotNull((Object) $receiver, (String) "$receiver");
Intrinsics.checkParameterIsNotNull((Object) str, (String) "str");
return $receiver.length() + str.length();
}
public static final void f() {
int len = ExampleKt.concatenatedLength("one string", "another string");
System.out.println(len);
}
}
这里还有更多的例子。
使用更新的KotlinEx,您可以直接在java中调用扩展
ExtensionFileName.foo(field1...)
基本上,它所做的是,让接收者作为第一个参数,其他参数保持在相同的位置
所以For。
你有extension(在extension .kt文件中)
Context.showToast(message:String){
...
}
在Java中,称之为as
ExtensionKt.showToast(context, message);
在文件中声明的所有Kotlin函数在默认情况下将被编译为相同包中的类中的静态方法,并具有来自Kotlin源文件的名称(首字母大写和“。将“kt”扩展名替换为“kt”后缀)。为扩展函数生成的方法将有一个附加的扩展函数接收器类型的第一个参数。
将其应用于原始问题,Java编译器将看到名称为example.kt的Kotlin源文件
package com.test.extensions
public fun MyModel.bar(): Int { /* actual code */ }
就像声明了下面的Java类一样
package com.test.extensions
class ExampleKt {
public static int bar(MyModel receiver) { /* actual code */ }
}
从Java的角度来看,扩展类不会发生任何变化,因此不能仅使用点语法来访问此类方法。但是它们仍然可以作为普通的Java静态方法调用:
import com.test.extensions.ExampleKt;
MyModel model = new MyModel();
ExampleKt.bar(model);
静态导入可以用于ExampleKt类:
import static com.test.extensions.ExampleKt.*;
MyModel model = new MyModel();
bar(model);
我有一个名为NumberFormatting的Kotlin文件。Kt有如下函数
fun Double.formattedFuelAmountString(): String? {
val format = NumberFormat.getNumberInstance()
format.minimumFractionDigits = 2
format.maximumFractionDigits = 2
val string = format.format(this)
return string
}
在java中,我简单地通过以下方式访问文件NumberFormattingKt后,所需的导入导入....extensions.NumberFormattingKt;
String literString = NumberFormattingKt.formattedFuelAmountString(item.getAmount());