
本文详解 Thymeleaf 中遍历字符串时因索引越界导致 charAt() 报错的原因,并提供基于序列索引、数组下标访问和字符数组迭代的三种健壮、简洁的解决方法。
本文详解 thymeleaf 中遍历字符串时因索引越界导致 `charat()` 报错的原因,并提供基于序列索引、数组下标访问和字符数组迭代的三种健壮、简洁的解决方法。
在 Thymeleaf 模板中,若需逐个渲染字符串的每个字符(如 name = "Alice" → 输出 A、l、i、c、e),直接使用 #numbers.sequence(0, #strings.length(name)) 配合 charAt(i) 易触发 IndexOutOfBoundsException。根本原因在于:#numbers.sequence(start, end) 的 end 是包含边界(inclusive),而字符串索引范围是 [0, length - 1]。例如当 name = "Hi"(长度为 2)时,#numbers.sequence(0, 2) 生成序列 [0, 1, 2],但 name.charAt(2) 尝试访问第 3 个字符,必然越界。
✅ 正确做法一:修正索引范围并使用数组语法(推荐)
<div th:each="i: ${#numbers.sequence(0, #strings.length(name) - 1)}">
<p th:text="${name[i]}"></p> <!-- 使用 name[i] 替代 name.charAt(i),更简洁且 Thymeleaf 原生支持 -->
</div>✅ 正确做法二:避免索引,直接遍历字符数组(最语义化)
<div th:each="c: ${name.toCharArray()}">
<p th:text="${c}"></p>
</div>该方式无需手动计算索引,代码可读性强,且完全规避越界风险。
⚠️ 注意事项:
- #strings.length(name) 返回 int,确保 name 非 null,否则模板渲染会抛出 NullPointerException。生产环境建议前置判空:
<div th:if="${name != null}"> <div th:each="c: ${name.toCharArray()}">...</div> </div> - name[i] 是 Thymeleaf 对字符串的扩展语法(等价于 String.charAt(i)),仅适用于 String 类型;对 List 或数组同样适用,但语义不同。
- 避免使用 #numbers.sequence(0, #strings.length(name)) 这类“多一位”的写法——这是初学者高频错误。
综上,优先推荐 toCharArray() + th:each 方案:它语义清晰、零索引计算、天然防越界,符合模板引擎“声明式渲染”的设计哲学。

















