【Debug-Arrays.asList()】java.lang.UnsupportedOperationException

报错:

java.lang.UnsupportedOperationException
        at java.util.AbstractList.add(AbstractList.java:404)
        at java.util.AbstractList.add(AbstractList.java:425)
        at com.xxxxxx.xxx.xxx.util.xxx$1.onResponse(xxx.java:75)        // 异常代码定位点
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:206)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:818)

分析:

代码出错的位置是位于一个OkHttp的网络请求onResponse()代码块内部的一部分,部分代码如下:

@Override
public void onResponse(Call call, Response response) throws IOException {
    String strData = response.body().string();
    // 通过逗号分隔成List
    List<String> list = Arrays.asList(strData.split(","));
    list.add("000");        // 崩溃点
    list.add(0, "111");
}

考虑了很多情况,包括子线程之类的都解决不了,最终感觉出问题的地方在于这个List不正经

参考:https://www.jianshu.com/p/2b113f487e5e

阅读官方文档,发现一句话:

Returns a fixed-size list backed by the specified array.
返回一个由指定数组生成的固定大小的List

尼玛坑爹啊, 人家的List本来就支持动态扩容的,偏偏这货(由Arrays.asList()方法生成的List)就是固定大小,固定大小就意味着任何改变其大小的操作(比如:add()/remove()等)都是不允许的。

为什么呢?查看Arrays.asList()源码:

    @SafeVarargs
    @SuppressWarnings("varargs")
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

方法中的的确确生成了一个 ArrayList ,这不应该是支持动态扩容的吗?别着急,接着往下看。紧跟在 asList 方法后面,有这样一个内部类:

private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable {
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;

        ArrayList(E[] array) {
            a = Objects.requireNonNull(array);
        }

// 省略...
}

这个内部类也叫 ArrayList ,更重要的是在这个内部类中有一个被声明为 final 的数组 a ,所有传入的元素都会被保存在这个数组 a 中。到此,谜底又揭晓了: asList() 方法返回的确实是一个 ArrayList ,但这个 ArrayList 并不是 java.util.ArrayList ,而是 java.util.Arrays 的一个内部类。这个内部类用一个 final 数组来保存元素,因此用 asList 方法产生的 ArrayList 是不可修改大小的

 

解决方案:创建一个真正的List

既然由Arrays.asList()方法创建出来的List是个“不正经”的List,不能动态改变容量,如果需要改变List的大小的时候,就要创建一个"货真价实"的List:

String[] arrStr = { "Apple", "Banana", "Orange" };
List<String> myList = new ArrayList<String>(Arrays.asList(arrStr));        // 货真价实的List
myList.add("Guava");

在上面这段代码中,我们 new 了一个 java.util.ArrayList ,然后再把 asList() 方法的返回值作为构造器的参数传入,最后得到的 myList 自然就是可以动态扩容的了。

 

参考:Arrays.asList使用指南

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值