这是ArrayList中内部类Itr中的next方法
大家有没有想过,明明第一个if语句判断了i是否>=size,为什么还要第二个if判断语句if (i >= elementData.length)?
这其实是为了防止反射攻击。大家想,不改变size大小,我们可以通过反射改变elementData数组的大小。改变数组的大小之后,ArrayList.this.elementData的数组已经是改变之后的了。所以,需要第二个if判断条件。
实现代码如下:
import java.util.ArrayList;
import java.util.Iterator;
public class IteratorExample {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
System.out.println("初始列表: " + list);
// 获取迭代器
Iterator<String> iterator = list.iterator();
// 模拟并发修改:直接修改底层数组
// 这是一个非常危险的操作,仅用于演示目的
System.out.println("模拟并发修改...");
// 这里我们直接缩小底层数组(正常情况下不应该这样做)
// 这模拟了另一个线程在迭代过程中修改了数据结构
Object[] elementData = null;
try {
java.lang.reflect.Field field = ArrayList.class.getDeclaredField("elementData");
field.setAccessible(true);
elementData = (Object[]) field.get(list);
// 创建一个更小的数组并替换
Object[] newArray = new Object[2]; // 比原数组小
System.arraycopy(elementData, 0, newArray, 0, 2);
field.set(list, newArray);
// 注意:我们没有更新modCount,这会造成不一致状态
} catch (Exception e) {
e.printStackTrace();
return;
}
System.out.println("尝试使用迭代器...");
try {
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println("下一个元素: " + element);
}
} catch (Exception e) {
System.out.println("捕获异常: " + e.getClass().getSimpleName() + ": " + e.getMessage());
e.printStackTrace();
}
}
}
运行结果如下: