Aarrays.asList产生的list对象在使用add或者remove方法时,抛异常java.lang.UnsupportedOperationException

博客指出Arrays.asList产生的list对象是其内部类ArrayList,并非java.utils.ArrayList对象。二者虽都继承AbstractList抽象类,但前者未重写add()和remove()方法,调用时会抛出java.lang.UnsupportedOperationException。
异常代码如下:
    public static void main(String[] args) {
        String[] strArr = {"1","2","3"};
        List<String> list = Arrays.asList(strArr);
        list.add("4");
    }
抛出异常:
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)
    at java.util.AbstractList.add(AbstractList.java:108)
    at com.yidu.edu.card.service.impl.UserWxappServiceImpl.main(UserWxappServiceImpl.java:375)
原因:

 Aarrays.asList产生的list对象是其内部类ArrayList, 而不是java.utils.ArrayList对象. 两个ArrayList都继承了AbstractList抽象类, 但是前者没有重写抽象类的add()和remove()方法, 如果调用, 则会抛出java.lang.UnsupportedOperationException;

AbstractList抽象类add和remove方法如下:
    /**
     * {@inheritDoc}
     *
     * <p>This implementation always throws an
     * {@code UnsupportedOperationException}.
     *
     * @throws UnsupportedOperationException {@inheritDoc}
     * @throws ClassCastException            {@inheritDoc}
     * @throws NullPointerException          {@inheritDoc}
     * @throws IllegalArgumentException      {@inheritDoc}
     * @throws IndexOutOfBoundsException     {@inheritDoc}
     */
    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     *
     * <p>This implementation always throws an
     * {@code UnsupportedOperationException}.
     *
     * @throws UnsupportedOperationException {@inheritDoc}
     * @throws IndexOutOfBoundsException     {@inheritDoc}
     */
    public E remove(int index) {
        throw new UnsupportedOperationException();
    }
# 解决 `UnsupportedOperationException` 异常 当调用 `DeviceIds.add("A")` 出 `UnsupportedOperationException` 异常,这通常是因为你尝试修改一个**不可变集合**。以下是详细分析和解决方案: ## 一、异常原因分析 ### 1. 常见场景 ```java List<String> DeviceIds = Arrays.asList("B", "C"); DeviceIds.add("A"); // UnsupportedOperationException ``` ### 2. 根本原因 - `Arrays.asList()` 返回的是**固定大小的集合**(基于原始数组的视图) - 这种集合不支持结构性修改(add/remove等操作) - 这是Java集合框架的设计决策,不是bug ## 二、解决方案 ### 方案1:创建新ArrayList(推荐) ```java List<String> DeviceIds = new ArrayList<>(Arrays.asList("B", "C")); DeviceIds.add("A"); // 正常工作 ``` ### 方案2:使用Java 9+的List.of(不可变) ```java List<String> DeviceIds = new ArrayList<>(List.of("B", "C")); DeviceIds.add("A"); // 正常工作 ``` ### 方案3:使用Collections工具类 ```java List<String> DeviceIds = new ArrayList<>(); Collections.addAll(DeviceIds, "B", "C"); DeviceIds.add("A"); // 正常工作 ``` ## 三、技术原理 ### 1. 不可变集合的特点 - 内存效率高(共享底层数组) - 线程安全(因为不可变) - 但无法进行修改操作 ### 2. 常见返回不可变集合的方法 | 方法/API | 可变性 | |-------------------------|-------| | Arrays.asList() | 部分不可变 | | List.of() (Java 9+) | 完全不可变 | | Collections.singletonList() | 不可变 | | Map.ofEntries() | 不可变 | ## 四、最佳实践 1. **明确集合需求**: - 如果只需要读取:使用不可变集合 - 如果需要修改:使用可变集合实现类 2. **防御性编程**: ```java // 返回不可修改的集合视图 public List<String> getDeviceIds() { return Collections.unmodifiableList(internalDeviceList); } ``` 3. **文档说明**: ```java /** * @return 返回的设备ID列表是只读的,如需修改请使用addDeviceId方法 */ public List<String> getDeviceIds() { return Collections.unmodifiableList(deviceIds); } ``` ## 五、其他语言对比 | 语言 | 默认集合行为 | 不可变集合API | |-------|------------|-----------------------| | Java | 可变 | Collections.unmodifiableXxx | | Kotlin| 不可变 | mutableListOf() | | C# | 可变 | ReadOnlyCollection | | Python| 可变 | tuple |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值