JvmStatic and JvmField annotations
JvmField
If you need to expose a Kotlin property as a field in Java, annotate it with the @JvmField
annotation. The field will have the same visibility as the underlying property. You can annotate a property with @JvmField
if it:
- has a backing field;
- is not private;
- does not have open, override or const modifiers;
- is not a delegated property.
class User(id: String) {
@JvmField val ID = id
}
// Java
class JavaClient {
public String getID(User user) {
return user.ID;
}
}
Late-Initialized properties are also exposed as fields. The visibility of the field will be the same as the visibility of lateinit property setter.
Kotlin properties declared in a named object or a companion object will have static backing fields either in that named object or in the class containing the companion object.
Annotating such a property with @JvmField
makes it a static field with the same visibility as the property itself.
class Key(val value: Int) {
companion object {
@JvmField
val COMPARATOR: Comparator<Key> = compareBy<Key> { it.value }
}
}
// Java
Key.COMPARATOR.compare(key1, key2);
// public static final field in Key class
JvmStatic
Kotlin represents package-level functions as static methods. Kotlin can also generate static methods for functions defined in named objects or companion objects if you annotate those functions as @JvmStatic
. If you use this annotation, the compiler will generate both a static method in the enclosing class of the object and an instance method in the object itself. For example:
class C {
companion object {
@JvmStatic fun callStatic() {}
fun callNonStatic() {}
}
}
Now, callStatic()
is static in Java while callNonStatic()
is not:
C.callStatic(); // works fine
C.callNonStatic(); // error: not a static method
C.Companion.callStatic(); // instance method remains
C.Companion.callNonStatic(); // the only way it works
Same for named objects:
object Obj {
@JvmStatic fun callStatic() {}
fun callNonStatic() {}
}
In Java:
Obj.callStatic(); // works fine
Obj.callNonStatic(); // error
Obj.INSTANCE.callNonStatic(); // works, a call through the singleton instance
Obj.INSTANCE.callStatic(); // works too
Starting from Kotlin 1.3, @JvmStatic
applies to functions defined in companion objects of interfaces as well. Such functions compile to static methods in interfaces. Note that static method in interfaces were introduced in Java 1.8, so be sure to use the corresponding targets.
interface ChatBot {
companion object {
@JvmStatic fun greet(username: String) {
println("Hello, $username")
}
}
}
@JvmStatic
annotation can also be applied on a property of an object or a companion object making its getter and setter methods static members in that object or the class containing the companion object.