增强型for循环仅支持实现了Iterable接口的集合和一维数组;不支持Map、多维数组、普通对象或未实现Iterator的自定义容器。

增强型for循环能遍历哪些类型
Java的增强型for循环(for-each)只支持实现了Iterable接口的集合,以及任意一维数组(无论基本类型还是引用类型)。它不支持普通对象、Map本身、多维数组(如int[][])或未实现Iterator的自定义容器。
-
ArrayList、LinkedList、HashSet✅ -
int[]、String[]、MyClass[]✅ -
HashMap❌(需用map.keySet()、map.values()或map.entrySet()转成可迭代结构) -
int[][]❌(只能遍历外层数组,得到的是int[];若要展开所有元素,必须嵌套一层for-each)
写法与常见错误:类型必须匹配
增强型for循环的声明变量类型必须与被遍历元素的实际类型一致,编译器不做自动拆箱/装箱推导(除极少数场景),否则直接报错Incompatible types。
String[] names = {"Alice", "Bob"};
for (Object s : names) { // 编译通过,Object是String的父类
System.out.println(s);
}
for (int i : names) { // 编译失败:incompatible types: String cannot be converted to int
}
- 遍历
Integer[]时,声明int会触发自动拆箱,但若数组含null,运行时抛NullPointerException - 遍历
int[]时,声明Integer会自动装箱,无空指针风险,但有额外对象开销 - 遍历
Collection extends Number>时,声明Number安全;声明Integer可能在运行时ClassCastException(如果实际含Double)
不能在遍历中修改集合结构
用增强型for循环遍历ArrayList、HashSet等集合时,任何调用add()、remove()、clear()等结构性修改方法的操作,都会触发ConcurrentModificationException——这不是线程问题,而是fail-fast机制在单线程下也会生效。
Listlist = new ArrayList<>(Arrays.asList("a", "b", "c")); for (String s : list) { if ("b".equals(s)) { list.remove(s); // 运行时报 ConcurrentModificationException } }
- 安全删除要用
Iterator.remove(),例如for (Iteratorit = list.iterator(); it.hasNext(); ) - 想边遍历边添加,应先收集待加元素,遍历完再
addAll() - 数组不受此限制(数组长度固定,
for-each只是读取),但改数组元素值本身是允许的
性能和语义:比传统for少什么,多什么
增强型for循环底层仍编译为传统for + Iterator(集合)或索引访问(数组),性能差异通常可忽略。但它明确表达了“只读遍历”的意图,也省去了索引管理与边界检查。
立即学习“Java免费学习笔记(深入)”;
- 对
LinkedList,增强型for比get(i)的传统for快得多(避免了O(n)随机访问) - 对
ArrayList,两者性能接近,但增强型for更简洁、不易越界 - 无法获取当前索引——需要索引时,必须退回传统
for (int i = 0; i - 无法反向遍历,也不能跳过元素(比如每两个取一个)
真正容易被忽略的是:它不提供对迭代过程的控制权。一旦开始,就只能顺序走完全部元素,中间不能break以外的流程干预——这既是约束,也是清晰性的来源。










