关于使用Arrays.asList导致java.lang.UnsupportedOperationException的问题探究

关于使用Arrays.asList导致java.lang.UnsupportedOperationException的问题探究

背景及问题

在日常开发工作中,我们经常需要将数组转换为List集合,从而使用集合提供的强大API。通常的做法是使用java.util.Arrays#asList方法,可以非常简单的做到数组转List,但在操作转换得到的集合时却发生意想不到的异常。
关于使用Arrays.asList导致java.lang.UnsupportedOperationException的问题探究

原因

下面我们来分析问题,从异常的堆栈信息我们可以得到引发异常的方法调用顺序及最终的异常抛出点.可以看出代码的确直接抛出了java.lang.UnsupportedOperationException.
关于使用Arrays.asList导致java.lang.UnsupportedOperationException的问题探究
那为什么我们平时使用ArrayList,LinkedList等集合时,却没有这个问题呢。这里我们可以大胆猜测,这里我们操作的List不是上述中的任何一种.我们可以通过查看源码或断点来查看java.util.Arrays#asList的返回值类型.
关于使用Arrays.asList导致java.lang.UnsupportedOperationException的问题探究
关于使用Arrays.asList导致java.lang.UnsupportedOperationException的问题探究
从源码和断点我们均可看出java.util.Arrays#asList返回的是ArrayList但不是java.util包下的ArrayList,而是java.util.Arrays的内部类.
我们来看下java.util.Arrays.ArrayList的结构,发现其没有实现自己的add方法,且继承了java.util.AbstractList,所以我们在使用add方法添加元素时,最终执行的是java.util.AbstractList的add方法,最终执行到上面截图的异常抛出点.至此问题分析也就结束了.关于使用Arrays.asList导致java.lang.UnsupportedOperationException的问题探究
ps:其实不止add方法会导致这个问题,remove,set等方法也会造成这个现象

解决

那么我们如何解决这个问题,其实很简单.我们自己重新new一个List并将转换得到的List作为构造方法的参数传进去,我们使用new出来的List即可.
关于使用Arrays.asList导致java.lang.UnsupportedOperationException的问题探究