从Java访问Kotlin扩展function
有没有可能从Java代码访问扩展函数?
我在Kotlin文件中定义了扩展function。
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似乎configuration正确。
我search了kotlin文档中的整个Java-interop文件,也search了很多,但是我找不到它。
我究竟做错了什么? 这甚至有可能吗?
在一个文件中声明的所有Kotlin函数将被默认编译为同一个包中的类中的静态方法,并且源自Kotlin源文件的名称(首字母大写和“.kt”扩展名replace为“Kt”后缀) 。 为扩展函数生成的方法将具有扩展函数接收器types的附加第一个参数。
将它应用到原始问题,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的angular度来看,扩展类没有任何反应,你不能只用点语法来访问这样的方法。 但是它们仍然可以作为普通的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);
Kotlin顶级扩展函数被编译为Java静态方法。
给定包含foo.bar
Kotlin文件Extensions.kt
包含:
fun String.bar(): Int { ... }
等效的Java代码将是:
package foo.bar; class ExtensionsKt { public static int bar(String receiver) { ... } }
除非,即Extensions.kt
包含该行
@file:JvmName("DemoUtils")
在这种情况下,Java静态类将被命名为DemoUtils
在Kotlin中,扩展方法可以用其他方式声明。 (例如,作为成员函数或作为伴随对象的扩展。)我将尽力在以后的日子扩大这个答案。
据我所知,这是不可能的。 从我阅读扩展文档看来,
public fun MyModel.bar(): Int { return this.name.length() }
创build一个签名的新方法
public static int MyModelBar(MyModel obj) { return obj.name.length(); }
然后,Kotlin将函数映射到forms为myModel.bar()
调用,其中如果在MyModel
类中找不到bar()
, MyModel
查找与输出的签名和命名scheme相匹配的静态方法。 请注意,这只是他们关于扩展名被静态导入的语句的一个假设,而不是覆盖已定义的方法。 我的源头还不够深入,无法确定。
所以,假设上述情况是真的,Kotlin扩展就没有办法从简单的旧Java代码中调用,因为编译器只会看到一个未知的方法被调用到一个对象上并出错。