Safe Call Operator
In this page:
val result = nullable?.property
val result = nullable?.method()
val result = a?.b?.c // null if any link is null
Basic Safe Call
?. calls a method or property only when the receiver is not null; if the receiver is null, the whole expression short-circuits to null without throwing.
Example: Basic Safe Call
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `name` (a `String?`), set to `"Kotlin"`
val name: String? = "Kotlin"
// Declare a read-only variable `nullName` (a `String?`), set to `null`
val nullName: String? = null
// Print `name?.length` to the console, with a trailing newline
println(name?.length)
// Print `nullName?.length` to the console, with a trailing newline
println(nullName?.length)
}
Login to try C/C++/Java/PHP code in the editor
Chaining Safe Calls
Multiple ?. operators can be chained together, such as user?.address?.city, and the entire chain evaluates to null the moment any part of it is null.
Example: Chaining Safe Calls
// Define a data class `Address`
data class Address(val city: String)
// Define a data class `Person`
data class Person(val name: String, val address: Address?)
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `personWithAddress`, set to `Person("Ana", Address("Berlin"))`
val personWithAddress = Person("Ana", Address("Berlin"))
// Declare a read-only variable `personWithoutAddress`, set to `Person("Bo", null)`
val personWithoutAddress = Person("Bo", null)
// Print `personWithAddress.address?.city` to the console, with a trailing newline
println(personWithAddress.address?.city)
// Print `personWithoutAddress.address?.city` to the console, with a trailing newline
println(personWithoutAddress.address?.city)
}
Login to try C/C++/Java/PHP code in the editor
Safe Calls with Function Calls
A safe call also works before calling a function, so text?.trim() only runs trim() if text is not null, producing null otherwise.
Example: Safe Calls with Function Calls
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `input` (a `String?`), set to `" hello "`
val input: String? = " hello "
// Declare a read-only variable `trimmed`, set to `input?.trim()`
val trimmed = input?.trim()
// Print "Trimmed: $trimmed" to the console, with a trailing newline
println("Trimmed: $trimmed")
}
Login to try C/C++/Java/PHP code in the editor
Safe Calls in Conditions
Safe calls combine naturally with equality checks, such as if (text?.length == 0), since comparing null to an Int simply evaluates to false rather than throwing.
Example: Safe Calls in Conditions
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `text` (a `String?`), set to `null`
val text: String? = null
// Check whether `text?.length == 0`
if (text?.length == 0) {
// Print "Empty string" to the console, with a trailing newline
println("Empty string")
// Otherwise, run this branch
} else {
// Print "Either not empty or null" to the console, with a trailing newline
println("Either not empty or null")
}
}
Login to try C/C++/Java/PHP code in the editor
- Using
.instead of?.on a nullable receiver, which the compiler rejects outright. - Chaining several
?.calls but forgetting the entire chain short-circuits tonullthe moment any link isnull. - Assuming
?.throws an exception onnull; it never throws, it simply evaluates tonullinstead.
?.calls a member only if the receiver is notnull; otherwise the whole expression evaluates tonull.- Chained safe calls like
a?.b?.cshort-circuit tonullas soon as any link in the chain isnull. ?.never throws an exception -- it is the safe alternative to a plain.on a nullable type.- The result of a safe call is always a nullable type, since it might be
null.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: