ArrayList中的源码解析

发布于:2025-09-09 ⋅ 阅读:(22) ⋅ 点赞:(0)

这是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();
        }
    }
}

运行结果如下:


网站公告

今日签到

点亮在社区的每一天
去签到