This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Framework 6.2.4!

The Elvis Operator

The Elvis operator (?:) is a shortening of the ternary operator syntax and is used in the Groovy language. With the ternary operator syntax, you often have to repeat a variable twice, as the following Java example shows:

String name = "Elvis Presley";
String displayName = (name != null ? name : "Unknown");

Instead, you can use the Elvis operator (named for the resemblance to Elvis' hair style). The following example shows how to use the Elvis operator in a SpEL expression:

  • Java

  • Kotlin

ExpressionParser parser = new SpelExpressionParser();

String name = parser.parseExpression("name ?: 'Unknown'").getValue(new Inventor(), String.class);
System.out.println(name);  // 'Unknown'
val parser = SpelExpressionParser()

val name = parser.parseExpression("name ?: 'Unknown'").getValue(Inventor(), String::class.java)
println(name)  // 'Unknown'

The SpEL Elvis operator also treats an empty String like a null object. Thus, the original Java example is only close to emulating the semantics of the operator: it would need to use name != null && !name.isEmpty() as the predicate to be compatible with the semantics of the SpEL Elvis operator.

As of Spring Framework 7.0, the SpEL Elvis operator supports java.util.Optional with transparent unwrapping semantics.

For example, given the expression A ?: B, if A is null or an empty Optional, the expression evaluates to B. However, if A is a non-empty Optional the expression evaluates to the object contained in the Optional, thereby effectively unwrapping the Optional which correlates to A.get().

The following listing shows a more complex example:

  • Java

  • Kotlin

ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();

Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
String name = parser.parseExpression("name ?: 'Elvis Presley'").getValue(context, tesla, String.class);
System.out.println(name);  // Nikola Tesla

tesla.setName("");
name = parser.parseExpression("name ?: 'Elvis Presley'").getValue(context, tesla, String.class);
System.out.println(name);  // Elvis Presley
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()

val tesla = Inventor("Nikola Tesla", "Serbian")
var name = parser.parseExpression("name ?: 'Elvis Presley'").getValue(context, tesla, String::class.java)
println(name)  // Nikola Tesla

tesla.setName("")
name = parser.parseExpression("name ?: 'Elvis Presley'").getValue(context, tesla, String::class.java)
println(name)  // Elvis Presley

You can use the Elvis operator to apply default values in expressions. The following example shows how to use the Elvis operator in a @Value expression:

@Value("#{systemProperties['pop3.port'] ?: 25}")

This will inject the value of the system property named pop3.port if it is defined or 25 if the property is not defined.