从Java访问Kotlin扩展函数

有没有可能从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文件,也搜索了很多,但是我找不到它。

我究竟做错了什么? 这甚至有可能吗?

在一个文件中声明的所有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); 

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() } 

创建一个签名的新方法

 public static int MyModelBar(MyModel obj) { return obj.name.length(); } 

然后,Kotlin将函数映射到形式为myModel.bar()调用,其中如果在MyModel类中找不到bar()MyModel查找与输出的签名和命名方案相匹配的静态方法。 请注意,这只是他们关于扩展名被静态导入的语句的一个假设,而不是覆盖已定义的方法。 我的源头还不够深入,无法确定。

所以,假设上述情况是真的,Kotlin扩展就没有办法从简单的旧java代码中调用,因为编译器只会看到一个未知的方法被调用对象和错误。