一、增强 for 循环是什么
增强 for 循环(Enhanced for loop),又叫 for-each 循环,是 Java 5 引入的一种简化写法,用来遍历:
- 数组(Array)
- 实现了
Iterable接口的集合(Collection、List、Set、Queue 等)
for (元素类型 变量名 : 集合或数组) {
// 使用变量名
}示例:
List<String> list = List.of("A", "B", "C");
for (String s : list) {
System.out.println(s);
}这段代码在表面上非常简洁,但底层其实会被编译器“翻译”成传统的迭代器写法。
二、底层原理:编译器自动替换成 Iterator
编译器在编译时会把上面代码自动生成如下等价代码 👇:
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
String s = it.next();
System.out.println(s);
}也就是说:
- 编译器会调用集合的
iterator()方法拿到一个Iterator对象; - 然后在循环中不断调用:
it.hasNext()判断是否还有下一个元素;it.next()获取下一个元素;
- 自动将每个元素赋值给循环变量
s。
这正是为什么增强 for 循环只适用于实现了 Iterable 接口的集合类。
三、数组的情况不同
增强 for 循环也支持数组,但数组没有 iterator() 方法。
因此编译器对数组的处理逻辑是不同的:它会生成一个普通的基于索引的 for 循环。
例如:
int[] nums = {1, 2, 3};
for (int n : nums) {
System.out.println(n);
}编译后相当于:
for (int i = 0; i < nums.length; i++) {
int n = nums[i];
System.out.println(n);
}四、增强 for 循环的限制
- 不能在循环体内修改集合结构
否则会抛出ConcurrentModificationException异常。
❌ 错误示例:
for (String s : list) {
if (s.equals("B")) {
list.remove(s); // 会报错
}
}✅ 正确写法:
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if (it.next().equals("B")) {
it.remove(); // 使用迭代器提供的 remove()
}
}- 无法获取元素下标
如果你需要索引(index),必须用普通 for 循环。 - 无法直接修改数组元素的值
(因为增强 for 拿到的是一个临时变量的副本)
int[] arr = {1, 2, 3};
for (int a : arr) {
a += 10; // 不会修改原数组
}
System.out.println(Arrays.toString(arr)); // 仍是 [1, 2, 3]特性 | 集合增强 for | 数组增强 for |
底层原理 | 使用 | 使用普通 for 循环(索引) |
是否依赖 | ✅ 是 | ❌ 否 |
是否可修改元素 | ❌ 不能(结构) | ✅ 可通过索引修改 |
是否可获取索引 | ❌ 否 | ✅ 通过普通 for 可实现 |
是否简化代码 | ✅ 大幅简化 | ✅ 简化数组遍历 |
五、Iterable 接口是什么?
Iterable 是 Java 集合体系中最顶层的接口之一,定义在 java.lang 包下,表示**“可迭代的对象”**。
它只定义了一个核心方法:
Iterator<T> iterator();也就是说,任何实现了 Iterable 接口的类,都必须提供一个返回 Iterator 对象的方法,这个迭代器能让我们一个一个地访问集合中的元素。
六、Collection 接口继承了 Iterable
Java 的集合框架(Collection Framework)中,Collection 接口继承了 Iterable,所有的集合类(例如 ArrayList、HashSet、LinkedList、ArrayDeque 等)都间接实现了 Iterable;所以它们都必须实现 iterator() 方法,并返回一个可以遍历自身元素的迭代器对象。

















