Kotlin Elvis Operator
The Elvis operator ?: provides a fallback value when a nullable expression returns null. Its name comes from its shape — ?: looks like a sideways face with slicked hair, similar to Elvis Presley's signature hairstyle.
The Problem It Solves
val username: String? = null
// Without Elvis — verbose
val display = if (username != null) username else "Guest"
// With Elvis — concise
val display = username ?: "Guest"
println(display) // GuestHow Elvis Works
expression ?: fallback
Is the left side null?
│
┌────────┴────────┐
YES NO
│ │
use fallback use left side
val name: String? = "Alice"
println(name ?: "Unknown") // Alice (name is not null)
val city: String? = null
println(city ?: "Unknown") // Unknown (city is null, use fallback)Elvis with Safe Call
Combining ?. and ?: is the most common null-handling pattern in Kotlin:
data class User(val name: String, val phone: String?)
val user: User? = User("Ravi", null)
val phone = user?.phone ?: "No phone on file"
println(phone) // No phone on file
val name = user?.name ?: "Anonymous"
println(name) // RaviChained Elvis
val a: String? = null
val b: String? = null
val c: String? = "Found it"
val result = a ?: b ?: c ?: "Default"
println(result) // Found itKotlin evaluates left to right and returns the first non-null value it finds.
Elvis with throw
The right side of Elvis can also throw an exception. This is useful for enforcing required values:
fun getUser(id: Int): String? = if (id == 1) "Alice" else null
fun main() {
val user = getUser(2) ?: throw IllegalArgumentException("User not found")
println(user)
}If getUser(2) returns null, an exception is thrown immediately with a clear message.
Elvis with return
fun printUserName(user: String?) {
val name = user ?: return // exit the function if null
println("Hello, $name!")
}
fun main() {
printUserName("Bob") // Hello, Bob!
printUserName(null) // (nothing printed, function returns early)
}Providing Default Numbers
val input: String? = null
val count: Int? = null
val length = input?.length ?: 0
val total = count ?: -1
println("Length: $length") // Length: 0
println("Total: $total") // Total: -1Practical Example: Dashboard Data
data class Stats(
val visits: Int?,
val revenue: Double?,
val topProduct: String?
)
fun printDashboard(stats: Stats) {
println("=== Dashboard ===")
println("Visits : ${stats.visits ?: 0}")
println("Revenue : ₹${stats.revenue ?: 0.0}")
println("Top Product: ${stats.topProduct ?: "N/A"}")
}
fun main() {
val full = Stats(1500, 45000.0, "Laptop")
val empty = Stats(null, null, null)
printDashboard(full)
println()
printDashboard(empty)
}Output:
=== Dashboard ===
Visits : 1500
Revenue : ₹45000.0
Top Product: Laptop
=== Dashboard ===
Visits : 0
Revenue : ₹0.0
Top Product: N/A