Java Interop

Java interop is Kotlin's ability to call Java code and be called by Java with no glue layer, sharing the same JVM, classes, and libraries seamlessly in both directions.

Learn Java Interop in our free Kotlin course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Kotlin course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

You'll handle Java's platform types and null, map getters to properties, and use @JvmStatic , @JvmOverloads , and @JvmField to make Kotlin friendly to Java callers.

What You'll Learn in This Lesson

1️⃣ Calling Java From Kotlin

Because both compile to JVM bytecode, Kotlin uses Java classes directly — every example here calls the JDK, which is Java. Java's getter/setter pairs appear as Kotlin properties (so sb.length , not sb.getLength() ), and Java statics are called as usual.

2️⃣ Platform Types and Null

Java carries no nullability information, so a Java return value arrives as a platform type ( String! ). Kotlin lets you treat it as nullable or non-null — but if you assume non-null and it's actually null, you get a crash. The safe habit: treat it as nullable and guard with ?: .

3️⃣ Making Kotlin Friendly to Java

When Java code will call your Kotlin, a few annotations smooth the path. @JvmStatic generates real statics from companion members; @JvmOverloads generates overloads for default arguments; @JvmField exposes a plain field; @JvmName renames a method as Java sees it.

From Kotlin these calls look ordinary; the annotations only change the bytecode Java sees. Lambdas also auto-convert to single-method Java interfaces — a SAM conversion — so executor.execute {' '} just works.

Your turn. Fill in the ___ blanks, then run and compare.

Expose a @JvmStatic function and a @JvmOverloads default-argument function.

📋 Quick Reference — Interop Annotations

Practice quiz

How does Kotlin see a Java getLength()/setLength() pair?

  • As a property named length
  • As two unrelated methods
  • As a constructor
  • As an interface

Answer: As a property named length. Kotlin maps JavaBeans getX/setX to property syntax, so it reads as length.

What is a 'platform type' in Kotlin?

  • A type that only runs on Android
  • A Java type whose nullability is unknown to Kotlin
  • A reified generic type
  • A sealed class

Answer: A Java type whose nullability is unknown to Kotlin. Java carries no nullability info, so its types arrive as platform types (String!).

What is the safe habit when using a Java return value?

  • Always assume it is non-null
  • Cast it to Any
  • Treat it as nullable and guard it
  • Wrap it in lazy

Answer: Treat it as nullable and guard it. Treat platform types as nullable and guard with ?: or ?. to avoid an NPE.

What does @JvmStatic on a companion-object function do?

  • Makes it private
  • Removes it from bytecode
  • Makes it nullable
  • Generates a real static method Java can call directly

Answer: Generates a real static method Java can call directly. @JvmStatic generates a real static so Java calls MyClass.member() directly.

What does @JvmOverloads generate for a function with default arguments?

  • Overloads so Java can omit the defaulted parameters
  • A nullable return type
  • A static field
  • A coroutine

Answer: Overloads so Java can omit the defaulted parameters. @JvmOverloads generates overloads omitting defaults, so Java can use shorter calls.

What does @JvmField expose a property as?

  • A private method
  • A plain public field with no getter/setter
  • A computed property
  • A companion object

Answer: A plain public field with no getter/setter. @JvmField exposes the property as a plain public field, bypassing get/set.

What is a SAM conversion?

  • Casting a String to Any
  • Converting Unit to void
  • Passing a lambda where a single-method interface is expected
  • Renaming a method for Java

Answer: Passing a lambda where a single-method interface is expected. SAM conversion lets a lambda stand in for a single-abstract-method interface.

How does a Kotlin function returning Unit appear to Java?

  • As returning Object
  • As returning Unit
  • As a void method
  • As returning null

Answer: As a void method. Kotlin maps Unit to Java's void for methods exposed to Java callers.

What does @JvmName let you control?

  • The name a method or file has as seen from Java
  • The nullability of a type
  • The thread a function runs on
  • The default argument values

Answer: The name a method or file has as seen from Java. @JvmName renames the generated method or file as Java sees it, resolving clashes.

How do you let your own Kotlin interface accept a lambda like a Java SAM?

  • Mark it @JvmStatic
  • Declare it with 'fun interface'
  • Make it abstract
  • Add @JvmField

Answer: Declare it with 'fun interface'. Declaring a single-method interface as a 'fun interface' enables lambda use in Kotlin.