这是一个普遍的问题。
假设我有一个用kotlin编写的扩展函数,该函数将DP转换为PX并返回NonNull Int

fun Int.toPx() {  /** implementation */ }

Java中的函数将如下所示
public int toPx(int $receiver) {  /** implementation */ }

在我看来,$receiver使Java互操作感产生而不再吸引人。

我知道您可以将@JvmName批注与@file:JvmName之类的某些组合一起使用来更改java中的名称。

当我尝试将@JvmNamereceiver网站目标结合使用时,它说

“此注释不适用于目标type usage和使用网站目标@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完成范围中。

10-08 18:00