这是一个普遍的问题。 假设我有一个用 kotlin 编写的扩展函数,它将 DP 转换为 PX 并返回一个 NonNull Int
fun Int.toPx() { /** implementation */ }
java中的函数看起来像这样
public int toPx(int $receiver) { /** implementation */ }
在我看来,$receiver
让 Java 互操作感觉生成和不受欢迎。
我知道您可以使用 @JvmName
注释和一些组合,如 @file:JvmName
来更改 java 中的名称。
当我尝试将 @JvmName
与 receiver
站点目标一起使用时,它会显示
"此注解不适用于目标类型用法
,使用站点目标@receiver
"
有没有办法克服这个问题并更改接收者的名称,如果没有,最好的选择是什么。
最佳答案
@JvmName
只能应用于文件的函数、属性访问器和顶级包外观。不支持参数名称。
基本上,您可以定义两个函数,一个带简单参数,另一个带接收器:
fun toPx(value: Int) { /* implementation */ }
fun Int.toPx() = toPx(this)
但是,不出所料,这不会编译,因为这两个函数将具有相同的 JVM 签名。因此,为了消除歧义,请将 @JvmName("...")
添加到扩展名中,并(可选)将扩展名标记为 inline
:
fun toPx(value: Int) { /* implementation */ }
@JvmName("toPxExtension") @Suppress("nothing_to_inline")
inline fun Int.toPx() = toPx(this)
要对Java隐藏扩展功能,您还可以annotate it with @JvmSynthetic
.
此解决方案的缺点是顶级函数 toPx
泄漏到查看包的文件的 IDE 完成范围内。
关于java - 更改 kotlin 扩展函数接收器 JVM 名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47775870/