猫王运算符
Elvis运算符(?:)是三元运算符语法的简化形式,用于Groovy语言中。使用三元运算符语法时,通常需要重复使用一个变量两次,如下面的Java示例所示:
String name = "Elvis Presley";
String displayName = (name != null ? name : "Unknown");
相反,你可以使用“猫王运算符”(因其外观与猫王的发型相似而得名)。以下示例展示了如何在SpEL表达式中使用该运算符:
- 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'
备注
SpEL Elvis 运算符也将 空 字符串视为 null 对象。因此,原始的 Java 例子只能近似地模拟该运算符的语义:要使其与 SpEL Elvis 运算符的语义兼容,需要使用 name != null && !name.isEmpty() 作为谓词。
提示
从Spring Framework 7.0开始,SpEL Elvis操作符支持java.util.Optional,并具有透明的解包语义。
例如,对于表达式A ?: B,如果A为null或一个*空的Optional,则该表达式的值为B。然而,如果A是一个非空的Optional,那么表达式的值就是Optional中包含的对象,这样就实际上解开了Optional的包装,相当于执行了A.get()。
以下列表展示了一个更复杂的例子:
- 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
提示
你可以在表达式中使用“Elvis操作符”来应用默认值。以下示例展示了如何在@Value表达式中使用“Elvis操作符”:
@Value("${systemProperties['pop3.port'] ?: 25}")
如果系统属性pop3.port被定义,就会注入该属性的值;如果该属性未定义,则会注入25。