kotlinkotlin-interopkotlin-java-interop

What's the use for Kotlin's @JvmSynthetic on a file target?


The @JvmSynthetic annotation is allowed to be used on a file, but I can't figure out what the purpose of this would be.

I was hoping I could hide a file containing a bunch of Kotlin-only extension methods from Java users, but that doesn't seem to be the case:

// Extensions.kt

@file:JvmSynthetic

@JvmSynthetic
fun Foo.mySyntheticExtension() = ...
fun Foo.myExtension() = ...
// Java usage

// This doesn't compile (as expected)
Extensions.mySyntheticExtension(foo);

// This compiles fine, so @JvmSynthetic on a file does not trickle down to all its functions
Extensions.myExtension(foo);

Even without the non-synthetic method Java users still see the cluttering ExtensionsKt class, although it appears empty to them.

If @file:JvmSynthetic doesn't hide the file('s generated class) from Java, nor trickles down the synthetic status to all functions in it, what is its intended purpose?


Solution

  • The original proposal that caused this annotation target to be added was KT-41884:

    The rationale given was:

    This would apply to the synthesized class which encapsulates top-level members. This allows hiding those members from Java when they are internal visibility.

    For example:

    // ManyInternals.kt, in module A
    @file:JvmSynthetic
    
    internal fun foo() {
    
    }
    
    internal fun bar() {
    
    }
    
    // Main.java, in module B
    public class Main {
        public static void main(String[] args) {
            ManyInternalsKt.foo(); // error
        }
    }