Kotlin by Example: Null Safety
Eliminating null pointer exceptions with this sample code demonstrating nullable and non-nullable types, safe call operator, Elvis operator for default values, and smart casts after null checks.
Code
fun main() {
// Non-nullable type (default)
var a: String = "abc"
// a = null // Compilation error
// Nullable type
var b: String? = "abc"
b = null // OK
// Safe call operator ?.
// Returns length if b is not null, else null
val l: Int? = b?.length
// Elvis operator ?:
// Returns length if b is not null, else -1
val l2: Int = b?.length ?: -1
// Not-null assertion operator !!
// Throws NullPointerException if b is null
// Use with caution!
try {
val l3 = b!!.length
} catch (e: NullPointerException) {
println("Caught NPE")
}
}Explanation
Kotlin's type system eliminates NullPointerExceptions by distinguishing between nullable and non-nullable references at compile time. Regular variables like String cannot hold null values by default. To allow null, the type must be explicitly marked with a question mark String?. This compile-time enforcement prevents accidental null dereferences that plague languages like Java.
Null safety operators in Kotlin include:
- Safe call operator
?.returns null if the receiver is null, otherwise calls the method or property - Elvis operator
?:provides a default value when the left-hand expression is null - Not-null assertion
!!throws NullPointerException if value is null - Safe cast
as?returns null instead of throwing ClassCastException on failed casts
Smart casts automatically convert nullable types to non-nullable within the scope of null checks. After checking if (b != null), the compiler treats b as non-nullable String inside the if block, eliminating redundant casts. This feature works with is type checks as well, automatically casting variables to the checked type.
Code Breakdown
var b: String? declares nullable type, allows null assignment.b?.length safe call returns Int?, null if b is null.?: -1 Elvis operator provides default value, unwraps nullable result.b!! not-null assertion throws NPE if null, use cautiously.
