225

I can't figure out what ?: does in for example this case

val list = mutableList ?: mutableListOf() 

and why can it be modified to this

val list = if (mutableList != null) mutableList else mutableListOf()
2
  • 27
    Return left side if it's not null, otherwise return right side. The first expression is short notation for the second expression. kotlinlang.org/docs/reference/null-safety.html#elvis-operator Commented Jan 14, 2018 at 19:07
  • That's the same as ?? in Flutter, which means if null then blah blah blah Commented Jul 4, 2023 at 11:52

11 Answers 11

237

TL;DR: If the resulting object reference [first operand] is not null, it is returned. Otherwise the value of the second operand (which may be null) is returned. Additionally, the operator can throw an exception if null is returned.


The Elvis operator is part of many programming languages, e.g. Kotlin but also Groovy or C#. I find the Wikipedia definition pretty accurate:

In certain computer programming languages, the Elvis operator ?: is a binary operator that returns its first operand if that operand is true, and otherwise evaluates and returns its second operand. It is a variant of the ternary conditional operator, ? :, found in those languages (and many others): the Elvis operator is the ternary operator with its second operand omitted.

The following is especially true for Kotlin:

Some computer programming languages have different semantics for this operator. Instead of the first operand having to result in a boolean, it must result in an object reference. If the resulting object reference is not null, it is returned. Otherwise the value of the second operand (which may be null) is returned. If the second operand is null, the operator is also able to throw an exception.

An example:

x ?: y // yields `x` if `x` is not null, `y` otherwise.
x ?: throw SomeException() // yields `x` if `x` is not null, throws SomeException otherwise
Sign up to request clarification or add additional context in comments.

2 Comments

C# does not have the Elvis operator in the strict sense. In C# we refer to ?. as the Elvis operator, but it is written differently - . instead of : - and it behaves differently - it is a safe navigation operator. Short-circuit OR operator || and null-coalescing operator ?? cover the behaviors of the original ?: operator, for booleans and references respectively.
It's also possible to use return in the same way as throw: x ?: return someValue yields x if x is not null and returns someValue otherwise.
173

The Elvis Operator is represented by a question mark followed by a colon: ?: and it can be used with this syntax:

first operand ?: second operand

It enables you to write a consise code, and works as such:

If first operand isn't null, then it will be returned. If it is null, then the second operand will be returned. This can be used to guarantee that an expression won't return a null value, as you'll provide a non-nullable value if the provided value is null.


For example(in Kotlin):

fun retrieveString(): String {    //Notice that this type isn't nullable
    val nullableVariable: String? = getPotentialNull() //This variable may be null
    
    return nullableVariable ?: "Secondary Not-Null String"
}

In this case, if the computed value of getPotentialNull is not null, it will be returned by retrieveString; If it is null, the second expression "Secondary Not-Null String" will be returned instead.

Also note that the right-hand side expression is evaluated only if the left-hand side is null.

In Kotlin, you could use any expression as second operand, such as a throw Exception expression

return nullVariable ?: throw IllegalResponseException("My inner function returned null! Oh no!")

The name Elvis Operator comes from the famous American singer Elvis Presley. His hairstyle resembles a Question Mark

Elvis QuestionMark

Source: Wojda, I. Moskala, M. Android Development with Kotlin. 2017. Packt Publishing

1 Comment

20 points for the origination!
54

This is called the Elvis operator and it does... Exactly what you've described in your question. If its left hand side is a null value, it returns the right side instead, sort of as a fallback. Otherwise it just returns the value on the left hand side.

a ?: b is just shorthand for if (a != null) a else b.

Some more examples with types:

val x: String? = "foo"
val y: String = x ?: "bar"      // "foo", because x was non-null    

val a: String? = null
val b: String = a ?: "bar"      // "bar", because a was null

1 Comment

if you come from java, it's more a shorthand for: a != null ? a : b
11

The elvis operator in Kotlin is used for null safety.

x = a ?: b

In the above code, x will be assigned the value of a if a is not null and b if a is null.

The equivalent kotlin code without using the elvis operator is below:

x = if(a == null) b else a

Comments

10

Let's take a look at the defintion:

When we have a nullable reference r, we can say "if r is not null, use it, otherwise use some non-null value x":

The ?: (Elvis) operator avoids verbosity and makes your code really concise.

For example, a lot of collection extension functions return null as fallback.

listOf(1, 2, 3).firstOrNull { it == 4 } ?: throw IllegalStateException("Ups")

?: gives you a way to handle the fallback case elgantely even if you have multiple layers of fallback. If so, you can simply chain multiply Elvis operators, like here:

val l = listOf(1, 2, 3)

val x = l.firstOrNull { it == 4 } ?: l.firstOrNull { it == 5 } ?: throw IllegalStateException("Ups")

If you would express the same with if else it would be a lot more code which is harder to read.

Comments

6

In addition to what has been already stated there is one good pattern that was not obvious for me, but which is common, e.g. you're writing a long function, but if something is null there is no sense to continue and the only thing you can do is to return from the function. Normally you'd write

something = expression
if (something == null) {
       return
}

With elvis it becomes shorter and more elegant:

something = expression ?: return

Comments

5

Consider below example,

var myStr:String? = null

//trying to find out length of myStr, but it could be null, so a null check can be put as,

val len = if (myStr != null){
    myStr.length
}
else{
    -1
}

Using the elvis operator, the above code can be written in a single line

val len = myStr?.length ?: -1     // will return -1 if myStr is null else will return length

Comments

4

Simply we can say that, you have two hands. You want to know, is your left hand working right now?. If left hand not working, return empty else busy

Example for Java:

private int a;
if(a != null){
    println("a is not null, Value is: "+a)
}
else{
    println("a is null")
}

Example for Kotlin:

val a : Int = 5
val l : Int = if (a != null) a.length else "a is null"

Comments

3

Basically, if the left side of Elvis returns null for some reason, returns the right side instead.

i.e.

val number: Int? = null
println(number ?: "Number is null")

So, if number is NOT null, it will print number, otherwise will print "Number is null".

Comments

3

A little addition though is this

X = A ?: B

X will still be null if both A and B evaluate to null

Therefore, if you want X to always be non-null, make sure B is always a non-null or that B always evaluates to non-null if it's a function or expression.

Comments

3

we use the Elvis operator to make sure we don't have a null in our result and if we have a null we determine how we deal with this null value by continuing in our program and returning a specific given value for example ** [if the left side is not null do code on the left side else do the code on right side ]

 val currentPage = params.key ?: 1 //If the current page is null get the first page.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.