是否可以从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();
但是,这不起作用 . The IDE won't recognize the bar() method and compilation fails.
使用kotlin的静态函数工作的是什么:
public fun bar(): Int {
return 2*2
}
通过使用 import com.test.extensions.ExtensionsPackage
所以我的IDE似乎配置正确 .
我搜索了kotlin文档中的整个Java-interop文件,并搜索了很多,但我找不到它 .
我究竟做错了什么?这有可能吗?
8 回答
在文件中声明的所有Kotlin函数将默认编译为同一包中的类中的静态方法,并且名称源自Kotlin源文件(首字母大写,".kt"扩展名替换为"Kt"后缀) . 为扩展函数生成的方法将具有带扩展函数接收器类型的附加第一参数 .
将其应用于原始问题,Java编译器将看到名为example.kt的Kotlin源文件
就好像声明了以下Java类一样
从Java的角度来看,扩展类没有任何反应,您不能只使用点语法来访问这些方法 . 但它们仍然可以作为普通的Java静态方法调用:
静态导入可用于ExampleKt类:
Kotlin顶级扩展函数被编译为Java静态方法 .
给出包含
foo.bar
的Kotlin文件Extensions.kt
包含:等效的Java代码是:
除非,即
Extensions.kt
包含该行在这种情况下,Java静态类将命名为
DemoUtils
在Kotlin中,可以通过其他方式声明扩展方法 . (例如,作为成员函数或作为伴随对象的扩展 . )我将尝试在以后扩展此答案 .
您需要在类文件中复制您的函数:
为ex Utils.kt创建Kotlin文件
输入代码
OR
In kotlin use:
In Java use this:
我有一个名为NumberFormatting.kt的Kotlin文件,它具有以下功能
在java中我简单地通过以下方式在文件 NumberFormattingKt 上访问它后需要导入
import ....extensions.NumberFormattingKt;
您始终可以通过转到
Tools > Kotlin > Show Kotlin Bytecode
,然后单击Decompile
来查看从Kotlin代码生成的 actual Java代码 . 这可以帮助你 . 在您的情况下,如果您有MyModelExtensions.kt
,Java代码将如下所示你可以通过在包含
bar
的文件上使用@JvmName
来改进这个:它将导致此代码:
使用
MyModels
与Effective Java对实用程序类的建议一致 . 您还可以像这样重命名方法:那么从Java方面来看,它看起来很惯用:
据我所知,这是不可能的 . 从我阅读扩展文档,它似乎
使用签名创建一个新方法
然后,Kotlin将该函数映射到
myModel.bar()
形式的调用,其中如果在MyModel
类中找不到bar()
,则它会查找与其输出的签名和命名方案匹配的静态方法 . Note that this is just an assumption from their statements about extensions being statically imported and not overriding defined methods. I haven't gotten far enough in their source to know for sure.因此,假设上述情况属实,则无法从普通的旧Java代码调用Kotlin扩展,因为编译器只会看到在对象上调用未知方法并出错 .
这里的其他答案涵盖了调用位于Kotlin包文件顶层的扩展函数的情况 .
但是,我的情况是我需要调用位于Class内的Extension函数 . 具体来说,我正在处理一个对象 .
解决方案非常简单 .
您所要做的就是将您的扩展功能注释为
@JvmStatic
,瞧!您的Java代码将能够访问并使用它 .当您扩展这样的类时:
它将编译为:
还有更多examples here .