为什么阿里巴巴Java开发手册强制要求Arrays.asList()不能使用其修改方法?

在阅读《阿里巴巴Java开发手册》时,发现有一条关于在 foreach 循环里进行元素的 remove/add 操作的规约,具体内容如下:

阿里巴巴Java开发手册

错误演示

我们首先在 IDEA 中编写一个在 foreach 循环里进行 remove 操作的代码:

import java.util.ArrayList;
import java.util.List;

public class ForEachTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("wupx");
        list.add("love");
        list.add("huxy");
        for (String temp : list) {
            if ("love".equals(temp)) {
                list.remove(temp);
            }
        }
        System.out.println(list);
    }
}

此时执行代码,编译正确,执行成功!输出 [wupx, huxy]。

接着我们把 “love” 换成 “wupx” 或是 “huxy” 再来运行下,执行结果如下:

纳尼,居然报错了,为什么第一次运行没有报错呢?让我们一起来进行探讨吧!

追根溯源

为了研究为什么会出现这样的情况,我们可以根据异常堆栈信息,去追踪错误,其中涉及到的部分源码如下:

private class Itr implements Iterator<E> {
    int cursor;       // 下一个要返回的元素的索引
    int lastRet = -1; // 返回的最后一个元素的索引(如果没有返回-1)
    int expectedModCount = modCount;

    public boolean hasNext() {
        return cursor != size;
    }

    public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public void forEachRemaining(Consumer<? super E> consumer) {
        Objects.requireNonNull(consumer);
        final int size = ArrayList.this.size;
        int i = cursor;
        if (i >= size) {
            return;
        }
        final Object[] elementData =

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

后端核心技术精讲 文章被收录于专栏

专注分享后端技术干货,包括 Java 基础、Java 并发、JVM、Elasticsearch、Zookeeper、Nginx、微服务、消息队列、源码解析、数据库、设计模式、面经等,助你编程之路少走弯路。

全部评论
原创不易,欢迎点赞、收藏、订阅三连!
点赞 回复 分享
发布于 2020-04-05 18:28

相关推荐

已老实求offer😫:有点像徐坤(没有冒犯的意思哈)
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务