SyntaxStudy
Sign Up
Kotlin Platform Types and Java Interop Nullability
Kotlin Beginner 1 min read

Platform Types and Java Interop Nullability

When Kotlin interoperates with Java, the compiler cannot always determine whether a Java value can be null. Values coming from Java are given a platform type, written as T! in error messages. Platform types are neither definitely nullable nor definitely non-nullable — the compiler allows you to use them as either, placing the burden of correctness on you. You can annotate Java code with @Nullable and @NotNull (from JetBrains, AndroidX, or JSR-305 packages) to give the Kotlin compiler precise information. Annotated Java APIs surface as proper Kotlin nullable or non-nullable types, restoring compile-time safety. Kotlin's standard library also provides runCatching, which wraps any expression in a Result, catching any Throwable and letting you handle success and failure through map, recover, getOrDefault, and related functions — a functional alternative to try/catch for nullable-safe code.
Example
// Demonstrating runCatching for safe error handling
fun riskyParse(input: String): Int {
    return input.toInt()   // throws NumberFormatException on bad input
}

fun safeParseWithResult(input: String): Result<Int> =
    runCatching { riskyParse(input) }

fun main() {
    // runCatching returns Result<T>
    val good = safeParseWithResult("42")
    val bad  = safeParseWithResult("abc")

    println(good.getOrDefault(0))   // 42
    println(bad.getOrDefault(0))    // 0

    good.onSuccess { println("Parsed: $it") }
    bad.onFailure  { println("Error: ${it.message}") }

    // map and recover on Result
    val transformed = bad
        .map    { it * 2 }
        .recover { -1  }
        .getOrNull()
    println("Recovered: $transformed")   // -1

    // Nullable return from standard library (similar to Java interop)
    val map = mapOf("key" to "value")
    val found: String? = map["key"]        // returns V? from Java Map
    val missing: String? = map["other"]

    println(found ?: "not found")    // value
    println(missing ?: "not found")  // not found

    // requireNotNull and checkNotNull
    val input: String? = "data"
    val safe = requireNotNull(input) { "Input must not be null" }
    println(safe.length)   // 4
}