SyntaxStudy
Sign Up
Kotlin The Kotlin Type System and Null
Kotlin Beginner 1 min read

The Kotlin Type System and Null

Kotlin's type system separates nullable types from non-nullable types at the language level. Every type T has a corresponding nullable counterpart T?. The compiler enforces that you cannot use a T? value in a context that expects T without an explicit null check or coercion, making null-related bugs visible at compile time rather than runtime. This design means that in practice the majority of variables in Kotlin code are non-nullable. You only reach for T? when the absence of a value is genuinely part of the domain — for example, a database record that might not exist, or a configuration key that was not supplied. The type hierarchy places Any at the top for non-nullable types and Any? for all types including nullable ones. Nothing is the bottom type used for functions that never return normally, such as those that always throw an exception.
Example
fun divide(a: Int, b: Int): Int? {
    return if (b == 0) null else a / b
}

// Type hierarchy demonstration
fun printType(value: Any?) {
    when (value) {
        null        -> println("null")
        is Int      -> println("Int: $value")
        is String   -> println("String: $value")
        is Boolean  -> println("Boolean: $value")
        else        -> println("Other: $value")
    }
}

// Function that never returns (return type = Nothing)
fun fail(message: String): Nothing {
    throw IllegalStateException(message)
}

fun main() {
    val result1 = divide(10, 2)
    val result2 = divide(10, 0)

    println(result1)   // 5
    println(result2)   // null

    // Compiler enforces null checks
    val r = result1 ?: fail("Division failed")
    println("Result: $r")   // 5

    printType(42)
    printType("hello")
    printType(null)
    printType(3.14)

    // Nullable collections vs collection of nullable
    val list1: List<Int?>  = listOf(1, null, 3)   // list of nullable Int
    val list2: List<Int>?  = null                  // nullable list

    val nonNull = list1.filterNotNull()
    println(nonNull)   // [1, 3]
}