title: Arrays.asList()使用中遇到的问题
date: 2020-04-17 14:08:37
categories:java
tags:
概述
Arrays
是java.util包中提供的工具类,主要用于对数组进行各种操作
Arrays.asList()
是该类中提供的一个静态方法,根据源码注释,作用为基于特定数组返回一个固定大小的列表
Returns a fixed-size list backed by the specified array
问题
运行如下代码时出现异常:
String[] strs={"str1","str2","str3","str4"};
List<String> arr=Arrays.asList(strs);
arr.add("str5");//抛出异常java.lang.UnsupportedOperationException
arr.remove("str1");//抛出异常java.lang.UnsupportedOperationException
System.out.println(arr);
这里通过Arrays.asList()将String数组转化为List,但对List进行add和remove操作时却报异常UnsupportedOperationException
,这是为啥呢,为什么操作不支持呢?
根据上述概述,该方法返回一个fixed-size
,即大小不能改变的列表,该方法的源码很简单,
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
由源码可知,该方法返回一个ArrayList
,那为啥ArrayList
就不支持add和remove操作了呢?
原来,这里的ArrayList
并不是java.util包中的集合类ArrayList
,而是在Arrays
类中自定义的一个内部类,其类的定义源码就在asList()
方法源码下;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SlsXF0hb-1589178740353)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420144009.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8x6YuRxF-1589178740354)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420144148.png)]
(话说为啥不换个名)
该内部类源码为
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
//内部源码省略
....
....
}
可以看到该类继承了AbstractList
类,并实现了RandomAccess
和Serializable
接口;该类源码中没有定义add,remove方法
进一步查看AbstractList
类源码
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
//部分源码省略
...
...
public boolean add(E e) {
add(size(), e);
return true;
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
//部分源码省略
...
...
}
可以看到,该类继承AbstraceCollection
类并实现List
接口,执行add,remove操作时均抛出UnsupportedOperationException
异常;
事实上,查看AbstraceList
类其余源码可以看到,其中set方法也抛出UnsupportedOperationException
异常,但ArrayList内部类重写了set方法,所以可以执行set操作
注意:
- 执行set操作时,如下代码,分别对数组和由数组转化的List集合元素进行修改
public static void main(String[] args) {
String[] strs={"str1","str2","str3","str4"};
List<String> list=Arrays.asList(strs);
System.out.println(Arrays.toString(strs));
System.out.println(list);
strs[0]="str1_new";//对strs进行修改
list.set(1,"str2_new");//对list进行修改
System.out.println(Arrays.toString(strs));
System.out.println(list);
}
结果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sSor2LLL-1589178740356)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420151851.png)]
发现对数组进行的修改影响到了集合,对于集合进行的修改也影响到了数组;
这是因为asList()
转化得到的集合元素直接引用了数组,数组和集合的变化会同步,这同时可能会导致一些编码上的问题
asList()
方法不可操作基本数据类型;因为由于通过new创建一个Arrays.ArrayList时,其参数为可变长泛型,而基本类型是无法泛型化的