Bird
Raised Fist0
Kotlinprogramming~10 mins

Kotlin annotations for Java callers (@JvmStatic, @JvmField) - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Kotlin annotations for Java callers (@JvmStatic, @JvmField)
Define Kotlin class/object
↓
Add @JvmStatic or @JvmField
↓
Compile Kotlin code
↓
Java code calls Kotlin members
↓
@JvmStatic: static method in Java
↓
@JvmField: direct field access in Java
Shows how adding @JvmStatic or @JvmField changes how Java code can call Kotlin members as static methods or direct fields.
Execution Sample
Kotlin
object Utils {
    @JvmStatic
    fun greet() = "Hello"

    @JvmField
    val version = 1
}
Defines a Kotlin object with a static method and a field accessible directly from Java.
Execution Table
StepActionKotlin MemberAnnotation EffectJava Call SyntaxResult
1Define object UtilsUtilsN/AN/AObject created with members
2Add @JvmStatic to greet()greet()Generates static method in JavaUtils.greet()"Hello" returned
3Add @JvmField to versionversionGenerates public static field in JavaUtils.versionValue 1 accessed directly
4Java calls Utils.greet()greet()Static method callUtils.greet()"Hello" returned
5Java accesses Utils.versionversionDirect field accessUtils.versionValue 1 accessed
6No annotation on other membersotherMemberNo static or direct fieldUtils.getOtherMember()Needs getter method
7End of exampleN/AN/AN/AExecution complete
💡 All annotated members are accessible as static or direct fields from Java; others use default Kotlin accessors.
Variable Tracker
VariableStartAfter Step 2After Step 3Final
Utils.greet()Not definedStatic method generatedStatic method unchangedStatic method available
Utils.versionNot definedNot definedStatic field generatedStatic field available
Key Moments - 3 Insights
Why does @JvmStatic make a Kotlin function callable as a static method in Java?
Because @JvmStatic tells the compiler to generate a static method in the Java bytecode, so Java can call it without an instance, as shown in execution_table step 2 and 4.
What difference does @JvmField make for Kotlin properties when accessed from Java?
It exposes the property as a public static field directly, skipping getter methods. See execution_table step 3 and 5 where Utils.version is accessed as a field.
What happens if you don't use these annotations on Kotlin members called from Java?
Java must use getter methods to access properties or instance methods, not static calls or direct fields, as noted in execution_table step 6.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what Java syntax calls the Kotlin function annotated with @JvmStatic?
AUtils.INSTANCE.greet()
Bnew Utils().greet()
CUtils.greet()
DUtils.getGreet()
💡 Hint
See execution_table row 4 showing Java calls Utils.greet() as a static method.
At which step does the Kotlin property become accessible as a direct static field in Java?
AStep 3
BStep 2
CStep 5
DStep 6
💡 Hint
Check execution_table row 3 where @JvmField generates the static field.
If you remove @JvmStatic from greet(), how would Java call change?
AJava calls Utils.greet() as static method
BJava calls Utils.INSTANCE.greet() as instance method
CJava calls Utils.getGreet()
DJava cannot call greet()
💡 Hint
Refer to key_moments about default Kotlin access from Java without @JvmStatic.
Concept Snapshot
Kotlin @JvmStatic annotation makes functions callable as static methods from Java.
@JvmField exposes Kotlin properties as public static fields in Java.
Without these, Java uses instance methods or getters.
Use in objects or companion objects for Java interoperability.
Improves Java code simplicity and performance.
Full Transcript
This visual execution shows how Kotlin annotations @JvmStatic and @JvmField affect Java interoperability. When you add @JvmStatic to a Kotlin function inside an object, the compiler generates a static method in Java, so Java code can call it directly without an instance. Similarly, @JvmField on a Kotlin property creates a public static field in Java, allowing direct access without getter methods. The execution table traces defining the Kotlin object, adding annotations, compiling, and how Java calls these members. Variables track the presence of static methods and fields after each step. Key moments clarify why these annotations matter and what happens without them. The quiz tests understanding of Java call syntax and annotation effects. The snapshot summarizes usage and benefits for Java callers. This helps beginners see exactly how Kotlin annotations change Java access step-by-step.

Practice

(1/5)
1. What is the main purpose of the @JvmStatic annotation in Kotlin when called from Java?
easy
A. To convert Kotlin lambdas into Java anonymous classes
B. To expose Kotlin properties as public fields in Java
C. To make a Kotlin function in a companion object appear as a static method in Java
D. To mark a Kotlin class as a Java interface

Solution

  1. 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.
  2. Step 2: Differentiate from @JvmField

    @JvmField exposes properties as fields, not functions. The question asks about functions, so @JvmStatic is correct.
  3. Final Answer:

    To make a Kotlin function in a companion object appear as a static method in Java -> Option C
  4. Quick Check:

    @JvmStatic = static method in Java [OK]
Hint: Remember: @JvmStatic = static method in Java [OK]
Common Mistakes:
  • Confusing @JvmStatic with @JvmField
  • Thinking @JvmStatic applies to properties
  • Assuming it changes Kotlin class types
2. Which of the following is the correct way to expose a Kotlin property as a public field accessible directly from Java?
easy
A. Annotate the property with @JvmStatic
B. Annotate the property with @JvmField
C. Declare the property as val without annotations
D. Use @JvmOverloads annotation

Solution

  1. Step 1: Identify the annotation for exposing fields

    @JvmField exposes Kotlin properties as public fields for direct Java access, bypassing getters/setters.
  2. Step 2: Eliminate other options

    @JvmStatic applies to functions, not properties. @JvmOverloads is for default parameters. val alone does not expose as field.
  3. Final Answer:

    Annotate the property with @JvmField -> Option B
  4. Quick Check:

    @JvmField = public field in Java [OK]
Hint: Use @JvmField to expose properties as fields [OK]
Common Mistakes:
  • Using @JvmStatic on properties
  • Assuming val exposes public field automatically
  • Confusing @JvmOverloads with field exposure
3. Given the Kotlin code below, what will be the output when called from Java?
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());
medium
A. Compilation error\nHello from instance
B. Hello from static\nCompilation error
C. Compilation error\nCompilation error
D. Hello from static\nHello from instance

Solution

  1. Step 1: Understand @JvmStatic effect on Java calls

    @JvmStatic makes greet() callable as a static method on Example class directly from Java.
  2. Step 2: Understand companion object function call

    greetInstance() is not annotated, so Java must call it via Example.Companion instance.
  3. Final Answer:

    Hello from static\nHello from instance -> Option D
  4. Quick Check:

    @JvmStatic allows direct static call, others via Companion [OK]
Hint: @JvmStatic = call directly on class; else use Companion [OK]
Common Mistakes:
  • Assuming all companion functions are static in Java
  • Trying to call unannotated functions as static
  • Ignoring the Companion object in Java calls
4. Identify the error in the Kotlin code below if the goal is to allow Java code to access count as a public field:
class Counter {
    companion object {
        var count = 0
    }
}
medium
A. Missing @JvmField on count
B. Missing @JvmStatic on count
C. Companion object cannot have properties
D. count must be declared as val not var

Solution

  1. Step 1: Understand property exposure to Java

    To expose a Kotlin property as a public field in Java, it must be annotated with @JvmField.
  2. Step 2: Check annotations and property modifiers

    @JvmStatic applies to functions, not properties. Companion objects can have properties. var is allowed.
  3. Final Answer:

    Missing @JvmField on count -> Option A
  4. Quick Check:

    Expose property as field = use @JvmField [OK]
Hint: Use @JvmField on properties for Java field access [OK]
Common Mistakes:
  • Using @JvmStatic on properties
  • Thinking companion objects can't have properties
  • Confusing var and val for Java exposure
5. You want to create a Kotlin utility class with a companion object that has a constant integer 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?
hard
A. class Utils { companion object { @JvmField val MAX = 100 @JvmStatic fun printMax() = println(MAX) } }
B. class Utils { companion object { val MAX = 100 fun printMax() = println(MAX) } }
C. class Utils { companion object { @JvmStatic val MAX = 100 @JvmField fun printMax() = println(MAX) } }
D. class Utils { companion object { const val MAX = 100 fun printMax() = println(MAX) } }

Solution

  1. Step 1: Expose constant as static field

    Use @JvmField on val MAX to expose it as a static field in Java.
  2. Step 2: Expose function as static method

    Use @JvmStatic on printMax() to make it callable as a static method from Java.
  3. 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.
  4. Final Answer:

    The code with @JvmField on MAX and @JvmStatic on printMax() -> Option A
  5. Quick Check:

    @JvmField for fields, @JvmStatic for static methods [OK]
Hint: Use @JvmField for fields and @JvmStatic for methods [OK]
Common Mistakes:
  • Swapping @JvmField and @JvmStatic annotations
  • Omitting annotations and expecting static access
  • Using const val without @JvmStatic on functions
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard