聊聊Arrays.asList()踩过的那些坑
Posted 赵侠客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊聊Arrays.asList()踩过的那些坑相关的知识,希望对你有一定的参考价值。
问题重现
日常开发中为了方便快捷的初始化一个List,经常会用到Arrays.asList()这个方法,不过有一次却出现了一个很奇怪的问题,测试代码如下:
@Test
public void test() {
List<Integer> ids=Arrays.asList(1,2);
ids.add(3);
}
运行结果
java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at com.zjrb.media.media.MediaTest.test(MediaTest.java:36)
这一段代码是不是太平常不过了?初始化一个List,然后再向List里增加一个元素,为什么会报操作不支持的错误呢?看来Arrays.adList()还是有坑的,所以这里总结一下这些坑。
1. add()、remove()、add()、removeAll() … 等添加/删除方法不可用
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);
}
}
查看Arrays.asList()的源码可以发现,方法返回的ArrayList 并不是 java.utill.ArrayList 而是 java.utill.arrays.ArrayList,而且存放数组变量是private final E[] a;
,这是个长度不可变的数组,所以List接口里的 add()、remove()、addAll()、removeAll()等增加、删除操作方法都不可用。当然修改数组中变量的值 set()方法还是可用的。
2. 不支持基本类型数组
测试代码如下
int [] a={1,2};
Integer [] b={1,2};
System.out.println(Arrays.asList(a));
System.out.println(Arrays.asList(b));
输出为:
[[I@cb29b75]
[1, 2]
因为public static <T> List<T> asList(T... a)
接收的参数是一个泛型T,基本类型不支持泛型,所以只能把int [] 数组当做一个引用参数,从而返回的List中只有一个值了,当然更不是你想要的值。
3. toArrays()方法返回数据类型不一样
java.utill.ArrayList测试代码:
List<Integer> a=new ArrayList<>();
a.add(1);
Object [] objects=a.toArray();
System.out.println(objects.getClass());
//输出class [Ljava.lang.Object;
Arrays.asList()测试代码:
List<Integer> a=Arrays.asList(1);
Object [] objects=a.toArray();
System.out.println(objects.getClass());
//输出 class [Ljava.lang.Integer;
Arrays.asList toArray()源码:
@Override
public Object[] toArray() {
return a.clone();
}
这些返回的是 T[]a 的clone(),返回的类型还是Integer [],只是向上转成了Object[]。
java.utill.ArrayList toArray()源码:
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
java.utill.ArrayList toArray()返回的就是Object[]类型。所以实际使用时要注意了。
4. 添加后再修改原参数坑
java.util.ArrayList测试代码
Integer [] a={1,2,3};
List<Integer> list=new ArrayList<>();
Collections.addAll(list,a);
a[0]=4;
System.out.println(list);
//输出 [1,2,3]
Arrays.asList测试代码:
Integer [] a={1,2,3};
List<Integer> list=Arrays.asList(a);
a[0]=4;
System.out.println(list);
//输出 [4, 2, 3]
Arrays.asList() 是调用a = Objects.requireNonNull(array);
,只是一个引用,所以修改原参数的值,数组中的值也会改变
总结
Arrays.asList() 目前发现这些坑,希望大家使用时要小心点,前人踩过的坑就不要再踩了。如果你还发现了其它坑欢迎交流分享!
以上是关于聊聊Arrays.asList()踩过的那些坑的主要内容,如果未能解决你的问题,请参考以下文章