Kotlin annotations for Java callers (@JvmStatic, @JvmField) - Time & Space Complexity
When Kotlin code is called from Java, certain annotations change how the code runs behind the scenes.
We want to see how these annotations affect the speed as the code runs with bigger inputs.
Analyze the time complexity of the following Kotlin code using @JvmStatic and @JvmField.
object Utils {
@JvmStatic
fun computeSum(numbers: List): Int {
var sum = 0
for (num in numbers) {
sum += num
}
return sum
}
@JvmField
val constantValue: Int = 42
}
This code defines a function to sum numbers and a constant value, both accessible from Java with special annotations.
Look for loops or repeated actions that affect speed.
- Primary operation: Looping through the list of numbers to add each one.
- How many times: Once for each number in the list (n times).
The time to add numbers grows as the list gets bigger because it adds each number once.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 additions |
| 100 | 100 additions |
| 1000 | 1000 additions |
Pattern observation: The work grows directly with the number of items.
Time Complexity: O(n)
This means the time to run the function grows in a straight line with the input size.
[X] Wrong: "Adding @JvmStatic or @JvmField makes the function run faster or slower."
[OK] Correct: These annotations only change how Java sees the code, not how many steps the code takes.
Understanding how annotations affect code behavior helps you explain how Kotlin and Java work together smoothly.
"What if we replaced the for-loop with a recursive function? How would the time complexity change?"
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
