# Java Interoperability — Kotlin

Source: https://www.skillbyai.com/en/kotlin/p-interop

> 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.

```kotlin
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.

**Quiz:** What does `@JvmStatic` on a companion object function do?

- [ ] Makes it run on a background thread
- [x] 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.
