Arrays.asList后执行add抛出java.lang.UnsupportedOperationException

1、问题描述

调用List的add(..)方法时,程序抛出了java.lang.UnsupportedOperationException,这个List由Arrays.asList(..)得到。代码如下: 

报错信息如下:

调试过程中,发现第一次进入for循环,执行到95行add(..)方法时,程序中断,抛出异常。

2、原因分析

调用add都能报错,可以看到报错信息:UnsupportedOperationException,即“不支持的操作异常”。
进入asList方法,可以看到,Arrays.asList(..)返回的是一个List,难道这list有什么特别的猫腻?

继续进入asList(..)方法中ArrayList<>(a)的源码中:

发现返回的这个ArrayList是java.util.Arrays的内部类,且继承自AbstractList<E>,并不是java.util.ArrayList<E>。

这个ArrayList和java.util.ArrayList<E>都继承自AbstractList<E>,且这个ArrayList并没有重写add(..)方法。

所以这个ArrayList调用的依然是AbstractList<E>中的add(..)方法,继续进入到AbstractList<E>里面看源码:

看起来没毛病,继续从108行进入,得到源码如下:

哈哈,问题找到了,这个方法没有执行任何操作,直接抛出一个UnsupportedOperationException,与报错信息是吻合的。

并且可以看出,不光add(..)方法,set和remove方法也都是直接抛出UnsupportedOperationException。

再回到Arrays的内部类ArrayList,并没有去重写上述方法,因此使用List.asList(..)返回的Arrays内部类ArrayList对象进行add等操作时会抛此异常。

作为对比,再看一下java.util.ArrayList<E>中,都是对上述几个方法进行了重写,源码如下:

因此通过new ArrayList()得到的List进行add等操作,不会抛异常。

至此,异常原因一目了然。

3、解决方法

方法一:

List<String> macList = new ArrayList<>(Arrays.asList(boundMacAddr.split(",")));

方法二:

List<String> macList = new ArrayList<>(); 
macList.addAll(Arrays.asList(boundMacAddr.split(",")));

实在不行,通过遍历,一个一个往新的list里加也是没有问题的。

猜你喜欢

转载自blog.csdn.net/lydia_cmy/article/details/99435891