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





