调用list.add方法报错(java.lang.UnsupportedOperationException)

今天在写一些统计,偶然写出如下段代码,跑了一下JUnit,竟然!!!调用list.add方法会报错(java.lang.UnsupportedOperationException)
代码段如下:

@Test
    public void test01() {

        List a7DaysTitleList = Arrays.asList("7日[0]","7日[1]","7日[2-10]","7日[10-30]");
        //a7DaysTitleList = new ArrayList({"7日[0]","7日[1]","7日[2-10]","7日[10-30]"});不存在的!

        for (String str : a7DaysTitleList) {
            System.out.println(str);
        }

        a7DaysTitleList.add("7日[30,+∞)");//报错

        for (String str : a7DaysTitleList) {
            System.out.println(str);
        }

    }

运行效果图:
调用list.add方法报错(java.lang.UnsupportedOperationException)_第1张图片

报错:java.lang.UnsupportedOperationException at java.util.AbstractList.add(AbstractList.java:131) at java.util.AbstractList.add(AbstractList.java:91) at com.markin.test.ListTest.test01(ListTest.java:21) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at …

怎么回事,调用add都能报错,可以看到报错信息提示“不支持的操作异常”!
可以看到,我使用Arrays.asList(xxx)来返回一个List的,难道,难道这list有什么特别的猫腻!
怕是要深入浅出一波源代码,走你:
按住Ctrl,鼠标点一下Arrays.asList(xxx),进入到Array类源代码中(Array.class)!注:反编译插件很好用!!!
调用list.add方法报错(java.lang.UnsupportedOperationException)_第2张图片
可以看到,调用Array的静态方法asList(xxx)返回的是一个ArrayList,
再深入,按住Ctrl,点进去ArrayList,重点来了,
调用list.add方法报错(java.lang.UnsupportedOperationException)_第3张图片
看到没有,看到没有,文件名有钱!(严肃点,咳咳是美元符号$),说明该ArrayList是Array的内部类!(内部类编译后会单独为一个文件,命名格式是:外部类+”美元符号”+内部类),好了,看到这,用个大红箭头标出来,
private final E[] a;
不过,不是说final修饰引用类型,是引用不可变,但是内容应该是可变的吗?!(这个知识点不清楚的欢迎骚扰)
对比了下Array内部的ArrayList和java.util.ArrayList的add方法,发现
Array内部的ArrayList没有重写AbstractList的add(xxx),导致我们上诉代码调用的add(xxx)其实是直接调用AbstractList类的add(xxx),所以直接抛出了异常UnsupportedOperationException。
调用list.add方法报错(java.lang.UnsupportedOperationException)_第4张图片
调用list.add方法报错(java.lang.UnsupportedOperationException)_第5张图片
好了,知道了为什么,怎么办呢,乖乖写new ArrayList(),一个一个add吧哈哈
调用list.add方法报错(java.lang.UnsupportedOperationException)_第6张图片

本来想用Collections.copy()方法实现复制,但是发生了错误Collections.copy 报错: Source does not fit in dest,解决:http://stackoverflow.com/questions/6147650/java-lang-indexoutofboundsexception-source-does-not-fit-in-dest
按文中提示:直接将原来的List,传入新的List的构造方法中即可
List dest = new ArrayList(source);

尾注:遇到问题,解决问题。


水平有限,小文如有错漏,请各路大神多指点。

你可能感兴趣的:(异常小记)