liveBook · Manning

Type system

As explained in Kotlin in Action, 2E

A type system is the set of rules a programming language uses to classify values and expressions and check their compatibility.

A type system classifies values and expressions, then restricts operations and assignments to compatible kinds of values. Kotlin uses static typing: the compiler knows types at compile time, while type inference often lets code omit explicit declarations. This keeps ordinary code concise without abandoning compile-time checks. section 1.2.2

Infer a type; make nullability explicit

val count: Int = 1 val inferred = 1 fun strLen(s: String) = s.length fun strLenSafe(s: String?): Int = if (s != null) s.length else 0 Both count and inferred are Int. By contrast, String excludes null, whereas String? permits it. A nullable value cannot be passed where String is required, and its members cannot be called until an if check establishes that it is non-null. section 1.2.2 section 7.2

This distinction makes a declared type more useful: a String value supports string operations, but Java’s String may also hold null, which requires extra checks before those operations are safe. Kotlin records that possibility in the type itself. Code that passes a potentially null value to a non-null parameter fails at compile time rather than producing many possible NullPointerExceptions at run time. section 7.3 section 7.2

Listing 7.1 Handling null values using if checks
fun strLenSafe(s: String?): Int =
    if (s != null) s.length else 0   #1
 
fun main() {
    val x: String? = null
    println(strLenSafe(x))
    // 0
    println(strLenSafe("abc"))
    // 3
}

Follow the null check that narrows a String? before calling length, with 0 returned when the value is null. section 7.2

Use Kotlin’s type rules to make intent visible:

  • Declare a non-null type when null is not an accepted input; callers must supply an actual value. section 7.2
  • Add ? to a type only when null is permitted, then handle that case before using the value as non-null. section 7.2
  • Rely on inference for obvious initializers, but add an explicit type where it communicates an important constraint. section 1.2.2

The type system also includes familiar object-oriented concepts such as classes, interfaces, and generics, plus first-class function types. Kotlin is designed to work with existing Java code, so these checks support incremental JVM development while aiming for compact, reliable, maintainable services. section 1.2.2 section 1.3.1

How Kotlin in Action, 2E covers it

How deep it goes
Explains static typing, inference, nullable and non-null types, assignment restrictions, and if-check narrowing; defers function-type detail.
Examples
Uses inferred Int values and String/String? length functions, including an if check that returns 0 for null.
What it assumes
Builds from familiar Java classes, interfaces, and generics while introducing Kotlin nullable types and inference directly.
What you can do after
Evaluate/understand whether Kotlin calls, assignments, and member access are allowed before running code.
How it connects
Connects static typing with type inference, nullable types, function types, generics, Java interoperability, and NullPointerException handling.

Also explained in

Compare how 6 books explain type system →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.