I have come across the @JvmSynthetic annotation in kotlin-stdlib, and I'm wondering what it is for, but, unfortunately, it is undocumented. (UPD: it was at that moment)
As far as I understand, applying it to a program element will add the synthetic modifier to the corresponding bytecode elements. As a consequence, the element becomes invisible from Java:
class MyClass {
@JvmSynthetic
fun f() { }
}
Somewhere in Java code:
MyClass c = new MyClass();
c.f() // Error: cannot resolve method f()
But the same elements are still visible in Kotlin code:
val c = MyClass()
c.f() // OK
Is hiding declarations from non-Kotlin sources a valid use of @JvmSynthetic? Is it the intended use? What are the other appropriate use cases?
Since @JvmSynthetic hides functions from Java, they cannot be overridden in Java either (and when it comes to an abstract member, the calls then result into AbstractMethodError). Given that, can I use @JvmSynthetic to prohibit overriding members of a Kotlin class in Java sources?
First, to answer what synthetic methods actually are, let's have a look at the Java language specification:
The
@JvmSyntheticannotation does exactly that: prevent access from source code. The method will still appear in reflection and is then marked as synthetic.More precisely, from the Kotlin documentation (emphasis mine):
As described in the last paragraph,
@JvmSyntheticis a tool for API design, which lets a library writer avoid automatic generation of Java equivalents. Probably the most popular use cases are Kotlin-only features, such as operator overloading,componentN()methods or properties, which may have a more idiomatic way to be exposed in Java.It is noteworthy that the target of this annotations are property setters/getters, functions and fields -- basically everything that translates in Java to a method.