一、 将数组转换成List,大家经常使用的方式是Arrays.asList,但是当使用转换后的List调用add()或者remove()方时抛出java.lang.UnsupportedOperationException异常,
为什么直接List strList= new ArrayList<>()调用add()或者remove()方时却可以正常操作,请看下文:
测试代码 复现
public class Test3 {
public static void main(String[] args) {
String[] strArray = {"1", "2", "3"};
List<String> strList = Arrays.asList(strArray);
try {
strList.add("4");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("strList : " + strList.toString());
System.out.println("-----------------");
List<String> strNewArrayList = new ArrayList<>();
strNewArrayList.add("1");
strNewArrayList.add("2");
strNewArrayList.add("3");
strNewArrayList.add("4");
System.out.println("strNewArrayList:" + strNewArrayList);
}
控制台打印结果:
可以看出strList.add(“4”)没有添加进来,抛出java.lang.UnsupportedOperationException异常,奇怪了,为什么strNewArrayList.add(“1”)…strNewArrayList.add(“4”)正常呢?
二、 问题分析:
Arrays.asList()源码如下:
asList() 方法直接 return new ArrayList<>(a);而这个 ArrayList;是Arrays类里的静态内部类,源码如下图:
从上面图片源码可以看出Arrays类里的静态内部类ArrayList是继承AbstractList,其构造函数需要传入数组参数,到这里我们知道Arrays.asList()是怎么将数组转换成List的了,重点来了,Arrays类里的静态内部类ArrayList是继承AbstractList,没有重写add()以及remove()方法,而是直接使用AbstractList类里的add()、remove()方法,源码如下:
从上面图片源码可以看出AbstractList类里面的add()方法直接抛出UnsupportedOperationException,到这里明白了Arrays.asList,但是当使用转换后的List调用add()或者remove()方时抛出java.lang.UnsupportedOperationException异常;
接下来看直接 new ArrayList<>(),ArrayList类也是继承AbstractList,不同的是ArrayList重写add()、remove()方法,源码如下:
从上面图片源码可以看出ArrayList类里的重写add()方法做了不同逻辑处理;
下面是修改后的代码,解决UnsupportedOperationException异常:
三、 总结
将数组通过Arrays.asList转化为List的时候,是不能对转化出来的结果进行add,remove操作的,因为它是Arrays里面的静态内部类ArrayList,它继承AbstractList,没有重写AbstractList里的add()、remove()方法,而AbstractList里的add()、remove()方法直接抛出UnsupportedOperationException异常;
而直接 new ArrayList<>()是java.util.ArrayList,ArrayList也是继承AbstractList,但是它重写add()、remove()方法并且做了相关逻辑处理。
解决UnsupportedOperationException异常方法是:将数组通过Arrays.asList转化为List传入new ArrayList<>()里得到新的List, 然后用新的List进行add()、remove()操作。
欢迎关注我的公众号,不定期推送优质的文章,
微信扫一扫下方二维码即可关注。