Kotlin中@JvmSynthetic的用途是什么?
我遇到了@JvmSynthetic
-stdlib中的@JvmSynthetic
注解,我想知道它是什么,但不幸的是,它是无证的。
据我所知,将其应用到程序元素将添加synthetic
修饰符到相应的字节码元素。 因此,元素在Java中变得不可见:
class MyClass { @JvmSynthetic fun f() { } }
Java代码中的某处:
MyClass c = new MyClass(); cf() // Error: cannot resolve method f()
但是在Kotlin代码中仍然可以看到相同的元素:
val c = MyClass() cf() // OK
隐藏来自非Kotlin资源的声明是否有效使用@JvmSynthetic
? 这是预期的用途吗? 什么是其他适当的用例?
由于@JvmSynthetic
隐藏了Java的函数,所以它们不能在Java中被覆盖(当涉及到一个abstract
成员时,这些调用将导致AbstractMethodError
)。 鉴于此,我可以使用@JvmSynthetic
来禁止在Java源代码中覆盖Kotlin类的成员吗?
在纯Java中, synthetic
方法由javac
编译器生成。 通常情况下,编译器必须在嵌套类上创建合成方法,当使用private修饰符指定的字段被封闭类访问时。
在java中给出以下类:
public final class SyntheticSample { public static void main(final String[] args) { SyntheticSample.Nested nested = new SyntheticSample.Nested(); out.println("String: " + nested.syntheticString); } private static final class Nested { private String syntheticString = "I'll become a method!"; } }
当SyntheticSample
类访问nested.syntheticString
字段时,确实调用了由编译器生成的静态synthetic
方法(名称类似于access$100
)。
即使Kotlin公开了能够“强制”创建合成方法的@JvmSynthetic
注解,我建议不要在普通的“用户”代码中使用它。 合成方法是编译器所做的低级技巧,我们不应该在日常代码中依赖这些东西。 我认为它支持标准库的其他部分,但如果你好奇的话,你应该直接询问JetBrains的人(尝试在官方的Kotlin论坛上 )