更改kotlin扩展函数接收器的JVM名称

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

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

java中的函数看起来像这样

 public int toPx(int $receiver) { /** implementation */ } 

在我看来, $receiver器使Java互操作感觉生成和不受欢迎。

我知道你可以用像@file:JvmName这样的组合来使用@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) 

另一种方法是用@JvmSynthetic联扩展进行注释 。 但是,内联也将取消通话开销。

此解决方案的缺点是顶级函数toPx泄漏到查看包的文件的IDE完成范围。