-
In Kotlin, the type system distinguishes between references that can hold null (nullable references) and those that cannot (non-nullable references). For example, a regular variable of type String cannot hold null:
var a: String = "abc" // Regular initialization means non-nullable by default a = null // compilation error
To allow nulls, you can declare a variable as a nullable string by writing String?:
var b: String? = "abc" // can be set to null b = null // ok print(b)
-
Compiler can check for null in condition:
val b: String? = "Kotlin" if (b != null && b.length > 0) { print("String of length ${b.length}") } else { print("Empty string") }
-
Your second option for accessing a property on a nullable variable is using the safe call operator ?.:
val a = "Kotlin" val b: String? = null println(b?.length) println(a?.length) // Unnecessary safe call
This returns b.length if b is not null, and null otherwise. The type of this expression is Int?.
-
When you have a nullable reference, b, you can say "if b is not null, use it, otherwise use some non-null value":
val l: Int = if (b != null) b.length else -1
Instead of writing the complete if expression, you can also express this with the Elvis operator ?::
val l = b?.length ?: -1
If the expression to the left of ?: is not null, the Elvis operator returns it, otherwise it returns the expression to the right. Note that the expression on the right-hand side is evaluated only if the left-hand side is null.
Since throw and return are expressions in Kotlin, they can also be used on the right-hand side of the Elvis operator.
fun foo(node: Node): String? { val parent = node.getParent() ?: return null val name = node.getName() ?: throw IllegalArgumentException("name expected") // ... }
-
The not-null assertion operator (!!) converts any value to a non-nullable type and throws an exception if the value is null.
val l = b!!.length
-
Regular casts may result in a ClassCastException if the object is not of the target type. Another option is to use safe casts that return null if the attempt was not successful:
val aInt: Int? = a as? Int