Annotations are used to attach metadata to code. This is created using the annotation keyword:
public annotation class JvmStatic
In the most common cases, annotations are used by annotation processing tools to generate or modify code. Let's look at the following example:
class Example1 {
companion object {
fun companionClassMember() {}
}
}
The Kotlin bytecode viewer shows the following code:
public final class Example1 {
public static final Example1.Companion Companion = new Example1.Companion((DefaultConstructorMarker)null);
public static final class Companion {
public final void companionClassMember() {
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
As you can see, the Example1 class contains the nested Companion class that contains the companionClassMember method. We can mark the companionClassMember method when the @JvmStatic annotation and the decompiled code to Java code version looks as follows:
public final class Example1 {
public static final Example1.Companion Companion = new Example1.Companion((DefaultConstructorMarker)null);
@JvmStatic
public static final void companionClassMember() {
Companion.companionClassMember();
}
public static final class Companion {
@JvmStatic
public final void companionClassMember() {}
private Companion() {}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
The preceding snippet contains the additional static companionClassMember function in the Example1 class that invokes the method of the Companion class. Using the @JvmStatic annotation, we tell the compiler to generate an additional method that can be used from the Java side.