关于Arrays.asList() 中的java.lang.UnsupportedOperationException异常

7 篇文章 0 订阅
2 篇文章 0 订阅

1、报错

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at 

2、原因

之前做项目的时候封装了一个工具类,用来数组和字符串之间的转换,发现异常是出现在 Arrays.asList() 中。

工具类详情见:Java 字符串和数组转换工具类

/**
 * 将字符串按指定字符串分割存入到List中
 *
 * @param str       [字符串]
 * @param separator [分隔符]
 * @return java.util.List<java.lang.String>
 */
public static List<String> stringToList(String str, String separator) {
    List<String> r = new ArrayList<>();
    if (BayouUtil.isNotEmpty(str)) {
        if (str.contains(separator)) {
            // 报错主要是由这里Arrays.asList()引起的
            r = Arrays.asList(str.split(separator));	
        } else {
            r.add(str);
        }
    }

    return r;
}

使用 asList 返回的是 Arrays 的内部类 ArrayList

@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
{
    private static final long serialVersionUID = -2764017481108945198L;
    private final E[] a;

    ArrayList(E[] array) {
        a = Objects.requireNonNull(array);
    }
......
}

而其继承的 AbstractList 父类中的 add()remove()clear() 方法中的底层最后都会抛出异常 。

public void add(int index, E element) {
    throw new UnsupportedOperationException();
}

public E remove(int index) {
    throw new UnsupportedOperationException();
}

private void rangeCheckForAdd(int index) {
    if (index < 0 || index > size())
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

List 接口中的 add()remove()clear()

image-20210810175025705

image-20210810175056375

因此在使用 asList 中的 add() remove() clear() 等方法最后都会抛出 UnsupportedOperationException 异常。

而为什么 ArrayList() 为什么不会报错?因为 ArrayList 中重写了 add removeclear 方法

public void add(E e) {
    checkForComodification();

    try {
        int i = cursor;
        ArrayList.this.add(i, e);
        cursor = i + 1;
        lastRet = -1;
        expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
        throw new ConcurrentModificationException();
    }
}

public void remove() {
    if (lastRet < 0)
        throw new IllegalStateException();
    checkForComodification();

    try {
        ArrayList.this.remove(lastRet);
        cursor = lastRet;
        lastRet = -1;
        expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
        throw new ConcurrentModificationException();
    }
}

public Object clone() {
    try {
        ArrayList<?> v = (ArrayList<?>) super.clone();
        v.elementData = Arrays.copyOf(elementData, size);
        v.modCount = 0;
        return v;
    } catch (CloneNotSupportedException e) {
        // this shouldn't happen, since we are Cloneable
        throw new InternalError(e);
    }
}

3、解决办法

r = new ArrayList<>(Arrays.asList(str.split(separator)));
// 或者
r.addAll(Arrays.asList(str.split(separator)));

注意:Arrays.asList()是个大坑,谨慎使用

原创博主:Little Tomcat
博主原文链接:https://mp.weixin.qq.com/s/p4wk0nlv7NCeT0694Se1Pw

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Little Tomato

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值