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.Optionalspring-doc.cadn.net.cn

例如,给定表达式A ?: B,如果Anull或一个emptyOptional, 则表达式评估为B。但是,如果A是一个非空的Optional,则表达式 评估为存储在Optional中的对象,从而有效地展开 Optional,这与A.get()相对应。spring-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