在并发环境下,arraylist 的 size() 与实际元素数可能不一致,导致循环中 i 超出实际范围,引发类似越界的现象。

循环里用 i 就会越界
Java 数组下标从 0 开始,最大合法索引是 array.length - 1。写成 i 看似“包含末尾”,实际多跑了一次——最后一次 <code>i 是 array.length,直接触发 ArrayIndexOutOfBoundsException。
常见于新手抄错 for 循环边界,或从其他语言(比如 Lua 的 1-based)迁移代码时没调整习惯。
- 正确写法永远是
i (推荐)或 <code>i (不推荐,易算错) - 增强 for 循环(
for (Type e : array))完全避开下标,适合只读遍历 - 如果必须用索引且要倒序,别写
i >= 0就完事——得确认起始值是array.length - 1,不是array.length
循环中动态修改集合长度却还用原 size() 当边界
ArrayList 或其他 List 在 for 循环里调用 remove() 或 add(),会导致元素前移/后移,但循环变量和终止条件没同步更新,下标很快对不上。
典型场景:过滤列表、批量删除满足条件的元素。
- 错误示范:
for (int i = 0; i —— 删除后后续元素前移,<code>i却继续加 1,跳过下一个元素,还可能越界 - 安全做法:用迭代器
Iterator.remove(),或倒序遍历(i = list.size() - 1; i >= 0; i--),或收集待删索引再批量删 - 注意:
list.size()是实时值,但 for 的终止条件只在每次循环开始时检查一次,不会动态重算
嵌套循环里混淆内外层数组长度
二维数组或双层 for 处理多个数组时,容易把内层循环的 length 写成外层数组的 length,尤其当两个数组长度接近时,测试难暴露。
酷纬企业网站管理系统Kuwebs是酷纬信息开发的为企业网站提供解决方案而开发的营销型网站系统。在线留言模块、常见问题模块、友情链接模块。前台采用DIV+CSS,遵循SEO标准。 1.支持中文、英文两种版本,后台可以在不同的环境下编辑中英文。 3.程序和界面分离,提供通用的PHP标准语法字段供前台调用,可以为不同的页面设置不同的风格。 5.支持google地图生成、自定义标题、自定义关键词、自定义描
比如遍历 String[] lines 和每个 line.split(",") 的字段,结果用 lines.length 当字段数上限。
- 错误写法:
for (int j = 0; j —— 这里 <code>fields是某一行拆出来的,长度跟lines无关 - 务必用当前数组的
.length:for (int j = 0; j - 如果不确定是否为空(如空行导致
fields是空数组),先判fields != null && fields.length > 0
并发环境下 ArrayList 的 size() 和实际元素数不一致
这不是传统“循环越界”,但现象一样:某次循环中 i 成立,进入循环体后,另一线程删了元素,<code>list.get(i) 仍抛 ArrayIndexOutOfBoundsException。
多见于日志处理、缓存刷新等未加锁却共享可变 List 的场景。
-
ArrayList不是线程安全的,size()和get()是两个独立操作,中间可能被修改 - 临时方案:用
Collections.synchronizedList()包一层,但需手动同步所有复合操作 - 更稳方案:改用
CopyOnWriteArrayList(适合读多写少),或改用不可变集合 + 每次生成新副本 - 别依赖“先 size 再 get”这种两步断言——它在并发下天然有竞态
越界问题本身简单,但真正麻烦的是它常藏在边界变化、多线程、嵌套结构这些“动起来”的地方。盯着 .length 和 size() 别写错只是第一关,得想清楚这个长度在循环执行过程中会不会变、被谁变、什么时候变。









