Arrays.asList()你真的知道怎么用吗?

打印 上一主题 下一主题

主题 889|帖子 889|积分 2667

发现问题

前几天在看别人的项目的时候,发现一个问题,简单复现一下这个问题
  1. // 注意这是一个Integer对象的数组哦
  2. Integer[] arr = new Integer[]{9999,88,77};
  3. List<Integer> list = Arrays.asList(arr);
  4. // 执行以下操作,有问题么?
  5. list.add(1);
  6. list.remove(0);
复制代码
好的,如果你觉得没错,和我刚开始的想法一致。在我没有认真学习这个asList方法时,天真的以为没有问题,顾名思义啊,就是把数组转换成List呗。
  1. // 恭喜,喜提报错,如果是这样测试该找你麻烦了,/(ㄒoㄒ)/~~
  2. Exception in thread "main" java.lang.UnsupportedOperationException
  3.         at java.util.AbstractList.add(AbstractList.java:148)
  4.         at java.util.AbstractList.add(AbstractList.java:108)
  5.         at TestForAsList.main(TestForAsList.java:13)
复制代码
废话不多说,我们直接进源码里面看看。
  1. @SafeVarargs
  2. @SuppressWarnings("varargs")
  3. public static <T> List<T> asList(T... a) {
  4.     return new ArrayList<>(a);  // 看起来没有任何异常,emm。然而呢,这个ArrayList并不是Java.util包下的ArrayList,而是一个在Arrays下实现的内部类。
  5. }
复制代码

我们发现这个静态内部类里面并没有实现List的add和remove方法。那么子类将延用父类AbstractList的方法实现,这个继承应没有什么问题。
  1. // 我们进入这个父类的实现,发现了报错的根源。。
  2. public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
  3.    
  4.         public void add(int index, E element) {
  5.         throw new UnsupportedOperationException();
  6.     }
  7.     public E remove(int index) {
  8.         throw new UnsupportedOperationException();
  9.     }
  10. }
复制代码
总结:
究其原因,就是这个asList方法返回的是一个内部类,只实现了一些遍历以及更新的方法。下次使用它的时候需要注意一下。
扩展知识点

数组值的变化

然后我就发现了这个很有意思的点,就是这个Arrays包下的ArrayList用的是构造器传进来的数组,并不像我们原来认为的ArrayList的那样会拷贝数组然后创建一个新的数组。
这意味着我们在对这个List进行set的改动时,我们同时会更改原数组的值
  1. public static void main(String[] args) {
  2.         Integer[] arr = new Integer[]{9999,88,77};
  3.         List<Integer> list = Arrays.asList(arr);
  4.         
  5.         list.set(1,0);
  6.         System.out.println(list.get(1));  // 输出0
  7.         System.out.println(arr[1]);  // 同样也输出了0
  8. }
复制代码
int[]数组

我们都知道int是基本数据类型,如果我们向asList()方法里面传入一个int[]数组会发生什么呢?
我们知道泛型的话需要的是对象类型,基础数据类型是不能作为泛型的。
  1. // 此时int[]会作为一个对象类型,然后转换为list。此时长度为1,且可以正常的取出来作为list元素
  2. public static void main(String[] args) {
  3.         int[] arr = new int[]{9999,88,77};
  4.         List<int[]> list = Arrays.asList(arr);
  5.         System.out.println(list.size());
  6.         System.out.println(list.get(0)[0]);
  7.         System.out.println(list.get(0)[1]);
  8.         System.out.println(list.get(0)[2]);
  9. }
复制代码
好了,asList()方法就学废了。一天学废一个小知识/dog

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天空闲话

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表