?: Elvis Operator
The ?: operator in Kotlin, known as the Elvis operator, returns the right-hand side value when the left-hand side is null. It lets you specify a default value for null in a concise way. You can also use return or throw on the right-hand side.
Syntax
// Elvis operator (?:)
val length = name?.length ?: 0 // Returns 0 if name is null
// Combined with return
fun processName(name: String?) {
val nonNull = name ?: return // Returns from the function if null
println(nonNull.uppercase())
}
// Combined with throw
fun requireName(name: String?): String {
return name ?: throw IllegalArgumentException("Name is required")
}
// Used in a chain
val value = a?.b?.c ?: "default"
Syntax Overview
| Syntax | Description |
|---|---|
| a ?: b | Returns b if a is null; otherwise returns a. |
| ?: return | Early-returns from the function when the value is null. |
| ?: throw exception | Throws an exception when the value is null. |
| ?: continue | Skips to the next iteration of a loop when the value is null. |
| ?: break | Exits the loop when the value is null. |
Sample Code
fun getName(id: Int): String? = if (id == 1) "Alice" else null
// Function that uses the Elvis operator to provide a default value
fun greet(name: String?) {
val displayName = name ?: "Anonymous"
println("Hello, $displayName!")
}
// Combined with return (guard clause pattern)
fun processUser(name: String?, age: Int?) {
val n = name ?: return // Returns immediately if null
val a = age ?: return
println("$n ($a years old)")
}
// Combined with throw
fun divide(a: Int, b: Int?): Int {
val divisor = b ?: throw ArithmeticException("Divisor is null")
return a / divisor
}
fun main() {
greet("Bob") // Hello, Bob!
greet(null) // Hello, Anonymous!
// Combining safe call with the Elvis operator
val name1 = getName(1)
val name2 = getName(99)
println(name1?.length ?: -1) // 5
println(name2?.length ?: -1) // -1
// Guard clause pattern
processUser("Alice", 25) // Alice (25 years old)
processUser(null, 25) // Nothing is printed
processUser("Bob", null) // Nothing is printed
// Combined with throw
try {
println(divide(10, 2)) // 5
divide(10, null) // Exception thrown
} catch (e: ArithmeticException) {
println("Exception: ${e.message}") // Exception: Divisor is null
}
// Chained calls with the Elvis operator
data class Address(val city: String?)
data class User(val address: Address?)
val user: User? = User(Address(null))
val city = user?.address?.city ?: "Unknown"
println("City: $city") // Unknown
// Usage with collections
val names = listOf("Alice", null, "Bob", null, "Carol")
val result = names.map { it ?: "Anonymous" }
println(result) // [Alice, Anonymous, Bob, Anonymous, Carol]
}
Notes
The Elvis operator is a Kotlin-specific alternative to the ternary operator. name ?: "default" is equivalent to Java's name != null ? name : "default", but more concise.
By placing return or throw on the right-hand side, you can implement guard clause patterns — such as "early return on null" or "throw on null" — in a compact form. This is especially useful for validating null values at the beginning of a function.
For the basics of nullable types, see Nullable Types / ?. Operator. For forcing a non-null value, see !! Non-null Assertion.
If you find any errors or copyright issues, please contact us.