Skip to content

4.12 默认表达式(Elvis运算符)

默认表达式是一种特殊的无 then 分支的条件表达式,等价于 Groovy 等语言中的 Elvis 运算符?:)。它允许你指定两个表达式:如果第一个表达式求值结果不为 null,则使用该结果;如果为 null,则使用第二个表达式的结果。

先看一个实际应用的例子:

html
<div th:object="${session.user}">
  ...
  <!-- 若 age 不为 null 显示年龄,否则显示 '(no age specified)' -->
  <p>Age: <span th:text="*{age}?: '(no age specified)'">27</span>.</p>
</div>

这段代码完全等价于完整的条件表达式写法,只是更简洁:

html
<p>Age: <span th:text="*{age != null}? *{age} : '(no age specified)'">27</span>.</p>

和普通条件表达式一样,Elvis 运算符的默认分支(第二个表达式)也可嵌套括号包裹的复杂表达式:

html
<p>
  Name: 
  <!-- 逻辑:firstName 非 null 则显示;否则判断是否为管理员,是则显示 'Admin',否则显示默认用户名 -->
  <span th:text="*{firstName}?: (*{admin}? 'Admin' : #{default.username})">Sebastian</span>
</p>

关键注意事项

  • 仅判断 null:Elvis 运算符不会处理空字符串(如 ${''}?: 'default' 结果仍为 ''),若需处理空字符串,需先用 #strings.isEmpty() 判断;
  • 优先级问题:嵌套表达式必须用括号包裹,否则会因运算符优先级导致逻辑错误: ❌ 错误:*{firstName}?: *{admin}? 'Admin' : #{default.username}(优先级混乱); ✅ 正确:*{firstName}?: (*{admin}? 'Admin' : #{default.username})(括号明确嵌套逻辑);
  • 与变量表达式兼容:无论是 ${...} 还是 *{...},Elvis 运算符的用法完全一致:
    html
    <!-- 普通变量表达式使用 Elvis 运算符 -->
    <p>Email: <span th:text="${user.email}?: 'no-email@example.com'">user@example.com</span></p>

总结

  1. Elvis 运算符 ?: 是 Thymeleaf 处理 null 默认值的简洁语法,等价于 (expr != null) ? expr : default
  2. 仅判断 null(不处理空字符串),需处理空字符串时需结合 #strings.isEmpty()
  3. 默认分支支持嵌套复杂表达式(需括号包裹),且兼容所有类型的 Thymeleaf 表达式,是模板中简化 null 判空逻辑的核心工具。