这是一个普遍的问题。
假设我有一个用kotlin编写的扩展函数,该函数将DP转换为PX并返回NonNull Int
fun Int.toPx() { /** implementation */ }
Java中的函数将如下所示
public int toPx(int $receiver) { /** implementation */ }
在我看来,
$receiver
使Java互操作感产生而不再吸引人。我知道您可以将
@JvmName
批注与@file:JvmName
之类的某些组合一起使用来更改java中的名称。当我尝试将
@JvmName
与receiver
网站目标结合使用时,它说“此注释不适用于目标
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完成范围中。