Lesson 21 / 25
Java Interoperability
Platform types, annotations and calling in both directions.
Two languages, one codebase
Kotlin calls Java directly: getters and setters appear as properties, and SAM interfaces accept lambdas. Values from Java have platform types (shown as String! in the IDE): the compiler does not know their nullability, so assign them to an explicitly nullable or non-null type at the boundary. Nullability annotations in Java, such as JetBrains @Nullable/@NotNull or JSpecify annotations, let Kotlin see real types. For Java callers of Kotlin code, annotations help: @JvmStatic exposes companion functions as static methods, @JvmOverloads generates overloads for default arguments, @JvmField exposes a property as a field, @JvmName renames, and @Throws declares checked exceptions for Java.
Making Kotlin friendly for Java callers
Annotations at the boundary.
import java.io.IOException
class Temperature private constructor(val celsius: Double) {
companion object {
@JvmStatic // Java: Temperature.ofCelsius(21.0)
fun ofCelsius(value: Double) = Temperature(value)
}
}
class HttpClientConfig @JvmOverloads constructor( // Java gets several constructors
val baseUrl: String,
val timeoutMs: Int = 5_000,
val retries: Int = 3,
)
@Throws(IOException::class) // visible to Java as a checked exception
fun readConfig(path: String): String = java.io.File(path).readText()
fun javaBoundary() {
val home: String? = System.getProperty("user.home") // platform type made explicit
println(home ?: "unknown")
}Pin down platform types early
Declare the Kotlin type explicitly when you receive a value from Java. Otherwise a null can travel far into Kotlin code before failing with a confusing NullPointerException.
Quick check: What does `@JvmStatic` on a companion object function do?
- Makes it run on a background thread
- Makes it callable from Java as a static method on the class
- Prevents Java from calling it
- Marks it as thread-safe
Answer
Makes it callable from Java as a static method on the class — Without it, Java must call it via the Companion instance.