我@JvmSynthetic在kotlin-stdlib中遇到了注释,我想知道它是什么,但不幸的是,它没有记录.
据我所知,将它应用于程序元素会将synthetic修饰符添加到相应的字节码元素.结果,该元素从Java变得不可见:
class MyClass {
@JvmSynthetic
fun f() { }
}
Run Code Online (Sandbox Code Playgroud)
Java代码中的某处:
MyClass c = new MyClass();
c.f() // Error: cannot resolve method f()
Run Code Online (Sandbox Code Playgroud)
但是在Kotlin代码中仍然可以看到相同的元素:
val c = MyClass()
c.f() // OK
Run Code Online (Sandbox Code Playgroud)
隐藏来自非Kotlin来源的声明是否有效使用@JvmSynthetic?它是预期用途吗?其他适当的用例是什么?
由于@JvmSynthetic隐藏了来自Java的函数,它们也无法在Java中被覆盖(当涉及abstract成员时,调用会产生AbstractMethodError).鉴于此,我可以@JvmSynthetic用来禁止在Java源代码中覆盖Kotlin类的成员吗?
在Kotlin中,当我有一个非公共成员并且inline fun调用它时,有一个编译错误说:
错误:(22,25)Kotlin:Public-API内联函数无法访问中
private fun f(): Unit定义的非公共APIcom.example
我找到了几种在公共场所调用我的函数的方法inline fun,但这是最好的方法吗?
假设我有一个private fun f() { }.然后我找到的选项是:
fun f() { }
把它公之于众.这是基线解决方案,但如果其他解决方案具有重大缺点,则最终可能会出现这种情况.
@PublishedApi internal fun f() { }
在Kotlin 1.1-M04中引入,注释可以应用于内部成员,使其有效公开.我注意到的含义是任何库用户仍然可以从Java代码中调用它,这就是我不喜欢它.
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") inline fun g() { f() }
在stdlib源中找到,这个注释似乎在应用于调用函数时抑制了错误.但它的局限性是什么?它只能用于inline功能吗?在某些情况下,最终的程序会失败吗?我尝试使用这个技巧从内联函数调用非内联函数,并且它有效,但它看起来很可疑.
@JvmSynthetic @PublishedApi internal fun f() { }
将第二个解决方案与字节码中的合成标志组合在一起.我不确定这是否正确用法@JvmSynthetic,但这似乎隐藏了Java代码的功能,这解决了问题@PublishedApi internal.
那么,哪种解决方案是从公共内联系统中调用非公共功能的最佳方式?我没有看到每个解决方案的缺点是什么?