java.lang.UnsupportedOperationException异常处理


初次碰见此类异常,深感大坑!写下此篇blog记录

报错源代码如下:

//memberIdList的定义  
//yjyProTopic.getMembersId()是中间带','的字符串
List<String> memberIdList = Arrays.asList(yjyProTopic.getMembersId().split(","));

//抛出异常代码  注:添加的元素类型为String
memberIdList.add(yjyProTopic.getCtoId());

看到这时发现很懵逼,为什么一个List类型的对象在调用add方法时报java.lang.UnsupportedOperationException异常呢?为此我百思不得其解


  • 进入Arrays源码

①定位到asList方法

/**
     * Returns a fixed-size list backed by the specified array.  (Changes to
     * the returned list "write through" to the array.)  This method acts
     * as bridge between array-based and collection-based APIs, in
     * combination with {@link Collection#toArray}.  The returned list is
     * serializable and implements {@link RandomAccess}.
     *
     * <p>This method also provides a convenient way to create a fixed-size
     * list initialized to contain several elements:
     * <pre>
     *     List&lt;String&gt; stooges = Arrays.asList("Larry", "Moe", "Curly");
     * </pre>
     *
     * @param <T> the class of the objects in the array
     * @param a the array by which the list will be backed
     * @return a list view of the specified array
     */
    @SafeVarargs
    @SuppressWarnings("varargs")
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

②发现asList内部是new了一个ArrayList对象,正当我以为它就是普普通通的ArrayList类时,Arrays源码中的下一行代码引起了我的注意

private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable{
    //...省略
}

③这里证明,此处new的ArraysList对象其实是Arrays的一个内部类的实例化对象(而不是java.util.ArraysList类的实例化对象),于是开始查看内部类ArraysList对象代码并比较区别

因为篇幅原因,此处省略各个类的代码展示,有兴趣的朋友自行查看

④比较完两个类的源代码我发现,虽然都是继承AbstractList<E>这个抽象类,但是在java.util.ArraysList类中重写了抽象类中的add、addAll、remove、removeAll等方法,但是在Arrays中的内部类ArrayList则没有重写这些方法,于是出现在使用这些未重写的方法时系统抛出java.lang.UnsupportedOperationException异常

⑤解决办法:

​ 在Arrays.asList后如需使用add、remove等此类方法,采用重新实例化一个java.util.ArrayList类对象

//改写后的代码
List<String> memberIdList = new ArrayList<>(Arrays.asList(yjyProTopic.getMembersId().split(",")));
最后修改:2020 年 12 月 31 日 10 : 37 AM
如果觉得我的文章对你有用,请随意赞赏