ArrayList中的源码解析
这是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();}}
}
运行结果如下: