What if your Kotlin code could speak Java's language perfectly without extra hassle?
Why Kotlin annotations for Java callers (@JvmStatic, @JvmField)? - Purpose & Use Cases
Imagine you wrote a Kotlin class with some functions and properties, but now you need to use it from Java code. You try to call those Kotlin members from Java, but the syntax is confusing and sometimes you can't access them directly.
Without special annotations, Java callers see Kotlin code differently. Static functions in Kotlin become instance methods in Java, and properties become getter/setter methods. This makes Java code verbose and error-prone, and sometimes you can't access what you want easily.
Using Kotlin annotations like @JvmStatic and @JvmField tells the compiler to generate Java-friendly code. @JvmStatic makes functions appear as static methods in Java, and @JvmField exposes properties as public fields. This makes calling Kotlin code from Java simple and natural.
class Utils { companion object { fun greet() = "Hello" val version = "1.0" } } // Java call: Utils.Companion.greet(); Utils.Companion.getVersion();
class Utils { companion object { @JvmStatic fun greet() = "Hello" @JvmField val version = "1.0" } } // Java call: Utils.greet(); Utils.version;
This lets Kotlin code feel natural and easy to use from Java, improving interoperability and reducing confusion.
When building Android apps, you often mix Kotlin and Java. Using these annotations helps Java parts call Kotlin utilities or constants cleanly without awkward syntax.
Calling Kotlin from Java can be confusing without help.
@JvmStatic and @JvmField make Kotlin members look like normal Java static methods and fields.
This improves code clarity and reduces errors when mixing Kotlin and Java.
Practice
@JvmStatic annotation in Kotlin when called from Java?Solution
Step 1: Understand the role of @JvmStatic
@JvmStatic makes functions inside Kotlin companion objects look like static methods in Java, so Java code can call them without an instance.Step 2: Differentiate from @JvmField
@JvmField exposes properties as fields, not functions. The question asks about functions, so @JvmStatic is correct.Final Answer:
To make a Kotlin function in a companion object appear as a static method in Java -> Option CQuick Check:
@JvmStatic = static method in Java [OK]
- Confusing @JvmStatic with @JvmField
- Thinking @JvmStatic applies to properties
- Assuming it changes Kotlin class types
Solution
Step 1: Identify the annotation for exposing fields
@JvmField exposes Kotlin properties as public fields for direct Java access, bypassing getters/setters.Step 2: Eliminate other options
@JvmStatic applies to functions, not properties. @JvmOverloads is for default parameters. val alone does not expose as field.Final Answer:
Annotate the property with @JvmField -> Option BQuick Check:
@JvmField = public field in Java [OK]
- Using @JvmStatic on properties
- Assuming val exposes public field automatically
- Confusing @JvmOverloads with field exposure
class Example {
companion object {
@JvmStatic
fun greet() = "Hello from static"
fun greetInstance() = "Hello from instance"
}
}
// Java code:
System.out.println(Example.greet());
System.out.println(Example.Companion.greetInstance());Solution
Step 1: Understand @JvmStatic effect on Java calls
@JvmStatic makes greet() callable as a static method on Example class directly from Java.Step 2: Understand companion object function call
greetInstance() is not annotated, so Java must call it via Example.Companion instance.Final Answer:
Hello from static\nHello from instance -> Option DQuick Check:
@JvmStatic allows direct static call, others via Companion [OK]
- Assuming all companion functions are static in Java
- Trying to call unannotated functions as static
- Ignoring the Companion object in Java calls
count as a public field:
class Counter {
companion object {
var count = 0
}
}Solution
Step 1: Understand property exposure to Java
To expose a Kotlin property as a public field in Java, it must be annotated with @JvmField.Step 2: Check annotations and property modifiers
@JvmStatic applies to functions, not properties. Companion objects can have properties. var is allowed.Final Answer:
Missing @JvmField on count -> Option AQuick Check:
Expose property as field = use @JvmField [OK]
- Using @JvmStatic on properties
- Thinking companion objects can't have properties
- Confusing var and val for Java exposure
MAX accessible as a static field from Java, and a function printMax() callable as a static method from Java. Which is the correct Kotlin code?Solution
Step 1: Expose constant as static field
Use @JvmField on val MAX to expose it as a static field in Java.Step 2: Expose function as static method
Use @JvmStatic on printMax() to make it callable as a static method from Java.Step 3: Verify other options
class Utils { companion object { val MAX = 100 fun printMax() = println(MAX) } } lacks annotations, so Java calls require Companion. class Utils { companion object { @JvmStatic val MAX = 100 @JvmField fun printMax() = println(MAX) } } swaps annotations incorrectly. class Utils { companion object { const val MAX = 100 fun printMax() = println(MAX) } } uses const val but no @JvmStatic on function.Final Answer:
The code with @JvmField on MAX and @JvmStatic on printMax() -> Option AQuick Check:
@JvmField for fields, @JvmStatic for static methods [OK]
- Swapping @JvmField and @JvmStatic annotations
- Omitting annotations and expecting static access
- Using const val without @JvmStatic on functions
Ready to prove it?
Pass the test and this pattern moves unknown
