调用ArrayList的add方法抛异常UnsupportedOperationException
调用ArrayList的add方法抛异常UnsupportedOperationException
对于一些想要把数组转成List的需求,可能会使用到Arrays.asList()获取List对象,但是这里面也存在一些问题。
示例代码如下
void test1(){
List<Object> list = Arrays.asList();
list.add("hello");
}
执行后报错信息为
java.lang.UnsupportedOperationException
at java.base/java.util.AbstractList.add(AbstractList.java:153)
at java.base/java.util.AbstractList.add(AbstractList.java:111)
at com.heima.item.test.test.test1(test.java:15)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
......
在上述代码中,list.add("hello")执行报错,异常为java.lang.UnsupportedOperationException,通过查看Arrays里的asList()方法可以看到如下信息
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
这边是new了一个新的ArrayList对象,有人可能以为这是我们所熟悉的那个ArrayList,但是其实不是,这是【java.util.Arrays.ArrayList】,而我们常用的ArrayList是【java.util.ArrayList】在Arrays的源码里面可以看到压根没有导入我们熟悉的那个ArrayList,而是定义了一个内部类。简单来说这是两个类,只是名字相同了,恰好都是ArrayList。
这个内部类是直接继承了AbstractList,它并没有重写add方法,所以我们调了add方法其实是调的AbstractList里的add方法,AbstractList里的add方法源码为
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
原因很明显,不重写的话一调就抛出异常UnsupportedOperationException。
不止add方法,set,remove这些方法也不能通过Arrays.asList得到的对象调用,具体可以参考Arrays和AbstractList这两个类的源码。
另辟蹊径:
方法一
对于想要通过asList来获取List对象,又想调用add方法的,可以使用下列方式得到java.util.ArrayList对象,没错这正是我们常用的List实例对象。
void test2(){
String [] strs = {"AAA", "BBB", "CCC"};
List<String> list1 = Arrays.asList(strs);
ArrayList<String> list2 = new ArrayList(list1);
list2.add("XXX");
list2.forEach(System.out::println);
}
通过这种方式,可以正常add元素进入list,遍历打印出来的结果如下
AAA
BBB
CCC
XXX
方法二
避免使用Arrays.asList,而是使用Collections.addAll来帮助我们把数组里的元素全部添加到List对象里。
void test3(){
String [] strs = {"AAA", "BBB", "CCC"};
List<String> list1 = Arrays.asList(strs);
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list2, strs);
list2.add("YYY");
list2.forEach(System.out::println);
}
遍历打印出来的结果如下
AAA
BBB
CCC
YYY
方法三
遍历复制元素。把java.util.Arrays.ArrayList里的元素遍历,然后一个个添加进入自己创建的java.util.ArrayList实例里。
void test4(){
String [] strs = {"AAA", "BBB", "CCC"};
List<String> list1 = Arrays.asList(strs);
ArrayList<String> list2 = new ArrayList<>();
list1.forEach(e -> {
list2.add(e);
});
list2.add("ZZZ");
list2.forEach(System.out::println);
}
遍历打印出来的结果如下
AAA
BBB
CCC
ZZZ
方法四
遍历复制元素。把java.util.Arrays.ArrayList里的所有元素一次性添加进入自己创建的java.util.ArrayList实例里。
void test5(){
String [] strs = {"AAA", "BBB", "CCC"};
List<String> list1 = Arrays.asList(strs);
ArrayList<String> list2 = new ArrayList<>();
list2.addAll(list1);
list2.add("OOO");
list2.forEach(System.out::println);
}
遍历打印出来的结果如下
AAA
BBB
CCC
OOO
方法五
直接创建java.util.ArrayList对象,使用for循环遍历数组然后add元素。
其他方法
还有一些没有介绍到的方式,比如List.copyOf,Stream API之类等等,最后都能得到想要的对象,但是不够简单。比较推荐使用常见的这几种方式。
调用ArrayList的add方法抛异常UnsupportedOperationException的更多相关文章
- ArrayList的add方法实现
ArrayList的底层是由数组实现,所以所有的操作都是围绕数组展开,要想理解add方法,就得先了解数组的增加,所以我们先实现一个数组的add,数组的添加可以从尾部增加或者其他位置插入, 如果在数组的 ...
- CloudStack的VO在调用setRemoved方法抛异常的原因
今天在开发中发现一个问题,本来想对一个VO对象的removed值赋值,然后去update一下这条记录,一个最简单的set方法,但是在调用时直接抛异常了. 1: public void setRemov ...
- ABP在领域事件中异步调用方法抛异常
在领域事件中调用UserRegistrationManager.RegisterAsync抛异常 Call UserRegistrationManager.RegisterAsync() throw ...
- 执行ArrayList的remove(object)方法抛异常?
简介 或许有很多小伙伴都尝试过如下的代码: ArrayList<Object> list = ...; for (Object object : list) { if (条件成立) { l ...
- 【Java】ArrayList 的 toArray() 方法抛出 ClassCastException 异常
第一次用这个方法,结果冒出个莫名其妙的异常来: String[] names = (String[]) mTags.toArray(); 结果会抛出 java.lang.ClassCastExcept ...
- 关于ArrayList add()方法 中的引用问题
ArrayList的add方法每次添加一个对象时,添加 的是一个对象的引用,比如进行循环操作10次 lists.add(a) 每次 a会改变 ,这时候你会发现你在lists里添加了10个相同的对象a ...
- 抛异常 throw的注意事项
子类覆盖父类只能抛出父类的异常或者子类或者子集注意:如果父类的方法没有抛异常,那么子类覆盖时绝对不能抛. 子类继承父类时,方法抛异常,要么抛父类,要么抛父类下的子类,不能抛父类平级或以上的异常 原因是 ...
- 【java】子类可以通过调用父类的public方法调用父类的private方法,为什么?
代码1: 打印结果: 代码2: 运行结果: 问题: 代码1中super是父类自己调用自己的add()方法,并在add()方法中调用了私有的del()方法,那为什么打印出来的this是子类? 代码2中t ...
- ArrayList调用remove(int index)抛出UnsupportedOperationException问题分析以及解决记录
使用Arrays转数组成为List后,不能调用add(...)和remove(...)方法,此时如果调用就会抛出UnsupportedOperationException异常 原因 其实Arrays. ...
- 浅析调用JSR303的validate方法, 验证失败时抛出ConstraintViolationException
废话不多说,直接进入正题:如何使用JSR303的validate,进行数据校验,失败后直接抛出异常加入流转信息中,并在form页面提示出来. 首先我们为了启用验证,需要向 项目中添加Bean验证的实现 ...
随机推荐
- css3 html5
vscode的使用 什么是HTML5? HTML5新增语义化标签 多媒体标签 <audio>音频标签 谷歌浏览器 把autoplay属性给我们禁用. 两种音频格式的播放 视频标签<v ...
- Java 数据类型的包装数据类型
什么是包装数据类型 Java是一个面向对象的编程语言,但基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型. 集合框架里面需要存储对象,不能存储基本数据类型,所以需要存储包装 ...
- yb课堂之高并发项目必备利器之分布式缓存和本地缓存 《十九》
什么是缓存? 程序经常要调用的对象存储在内存中,方便其使用时可以快速调用,不必去数据库或者其他持久化设备中查询,主要就是提高性能 DNS.前端缓存.代理服务器缓存Nginx.应用程序缓存(本地缓存.分 ...
- yb课堂之订单列表接口开发 《十七》
订单列表接口开发 VideoOrderController.java VideoOrderService.java VideoOrderServiceImpl.java VideoOrderMappe ...
- Maven Helper插件——实现一键Maven依赖冲突问题
业余在一个SpringBoot项目集成Swagger2时,启动过程一直出现以下报错信息-- An attempt was made to call a method that does not exi ...
- 从基础到高级应用,详解用Python实现容器化和微服务架构
本文分享自华为云社区<Python微服务与容器化实践详解[从基础到高级应用]>,作者: 柠檬味拥抱. Python中的容器化和微服务架构实践 在现代软件开发中,容器化和微服务架构已经成为主 ...
- 可视化—gojs 超多超实用经验分享(四)
目录 41.监听连线拖拽结束后的事件 42.监听画布的修改事件 43.监听节点被 del 删除后回调事件(用于实现调用接口做一些真实的删除操作) 44.监听节点鼠标移入移出事件,hover 后显示特定 ...
- 第八节 JMeter基础-高级登录【数据库数据驱动】
声明:本文所记录的仅本次操作学习到的知识点,其中商城IP错误,请自行更改. 背景:获取数据库用户表中的数据进行登录接口测试.思路: 引用jar包[测试计划]. 设置数据库的连接信息,取变量名db1-- ...
- GIS前沿技术
无论是初步接触到GIS的学生,还是对GIS已经有一定的了解的从业者,肯定都非常关心两个问题:GIS有没有发展前景,GIS有哪些应用价值? 关于这两个问题,笔者的答案是GIS作为一门融合了空间数据采集. ...
- mybatisplus实现一次多表联查+分页查询
众所周知,mybatisplus非常好用,但是他不好用就不好用在不可以多表联查.在mybatisplusjoin中提供了联查的方法,那个参数我没看懂Orz 不过,历经千辛万苦,我通过xml终于写出来了 ...