Elvis 运算符

Elvis 运算符(?:)是对三元运算符语法的一种简化形式,用于Groovy语言中。使用三元运算符语法时,通常需要重复写两次同一个变量,如下所示的 Java 示例:spring-doc.cadn.net.cn

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

相反,你可以使用 Elvis 运算符(因其形似猫王 Elvis 的发型而得名)。 以下示例展示了如何在 SpEL 表达式中使用 Elvis 运算符:spring-doc.cadn.net.cn

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'

SpEL 的 Elvis 运算符还将empty字符串视作 null 对象。因此,原始的 Java 示例仅近似模拟了该运算符的语义:为了与 SpEL Elvis 运算符的语义兼容,它需要使用 name != null && !name.isEmpty() 作为判断条件。spring-doc.cadn.net.cn

从 Spring Framework 7.0 开始,SpEL 的 Elvis 操作符支持 java.util.Optional,并具有透明的解包语义。spring-doc.cadn.net.cn

例如,给定表达式 A ?: B,如果 Anull 或一个emptyOptional, 则该表达式的计算结果为 B。然而,如果 A 是一个非空的 Optional,则该表达式 的计算结果为包含在 Optional 中的对象,从而有效地解包与 A.get() 对应的 Optionalspring-doc.cadn.net.cn

以下列表展示了一个更复杂的示例:spring-doc.cadn.net.cn

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

您可以使用 Elvis 运算符在表达式中应用默认值。以下示例展示了如何在 @Value 表达式中使用 Elvis 运算符:spring-doc.cadn.net.cn

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

如果定义了名为 pop3.port 的系统属性,则注入其值;如果该属性未定义,则注入 25spring-doc.cadn.net.cn