Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
319 views
Welcome To Ask or Share your Answers For Others

1 Answer

In plain Java, synthetic methods are generated by the javac compiler. Normally the compiler must create synthetic methods on nested classes, when fields specified with the private modifier are accessed by the enclosing class.

Given the following class in 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!";
    }
}

when the SyntheticSample class accesses the nested.syntheticString field, it is indeed calling a static synthetic method generated by the compiler (named something like access$100).

Even if Kotlin exposes a @JvmSynthetic annotation that is able to "force" the creation of synthetic methods, I advice to not using it in normal "user" code. Synthetic methods are low-level tricks made by the compiler, and we should never rely on such things in everyday code. I think it's there to support other parts of the standard library, but you should ask the JetBrains guys directly if you're curious (try on the official Kotlin Discussion Forum)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...