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里加也是没有问题的。