发现问题

前几天在看别人的项目的时候,发现一个问题,简单复现一下这个问题

// 注意这是一个Integer对象的数组哦
Integer[] arr = new Integer[]{9999,88,77};
List<Integer> list = Arrays.asList(arr);
// 执行以下操作,有问题么?
list.add(1);
list.remove(0);

好的,如果你觉得没错,和我刚开始的想法一致。在我没有认真学习这个asList方法时,天真的以为没有问题,顾名思义啊,就是把数组转换成List呗。

// 恭喜,喜提报错,如果是这样测试该找你麻烦了,/(ㄒoㄒ)/~~
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at TestForAsList.main(TestForAsList.java:13)

废话不多说,我们直接进源码里面看看。

@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a); // 看起来没有任何异常,emm。然而呢,这个ArrayList并不是Java.util包下的ArrayList,而是一个在Arrays下实现的内部类。
}

我们发现这个静态内部类里面并没有实现List的add和remove方法。那么子类将延用父类AbstractList的方法实现,这个继承应没有什么问题。

// 我们进入这个父类的实现,发现了报错的根源。。
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { public void add(int index, E element) {
throw new UnsupportedOperationException();
} public E remove(int index) {
throw new UnsupportedOperationException();
}
}

总结:

究其原因,就是这个asList方法返回的是一个内部类,只实现了一些遍历以及更新的方法。下次使用它的时候需要注意一下。

扩展知识点

数组值的变化

然后我就发现了这个很有意思的点,就是这个Arrays包下的ArrayList用的是构造器传进来的数组,并不像我们原来认为的ArrayList的那样会拷贝数组然后创建一个新的数组。

这意味着我们在对这个List进行set的改动时,我们同时会更改原数组的值

public static void main(String[] args) {
Integer[] arr = new Integer[]{9999,88,77};
List<Integer> list = Arrays.asList(arr); list.set(1,0);
System.out.println(list.get(1)); // 输出0
System.out.println(arr[1]); // 同样也输出了0
}

int[]数组

我们都知道int是基本数据类型,如果我们向asList()方法里面传入一个int[]数组会发生什么呢?

我们知道泛型的话需要的是对象类型,基础数据类型是不能作为泛型的。

// 此时int[]会作为一个对象类型,然后转换为list。此时长度为1,且可以正常的取出来作为list元素
public static void main(String[] args) {
int[] arr = new int[]{9999,88,77};
List<int[]> list = Arrays.asList(arr);
System.out.println(list.size());
System.out.println(list.get(0)[0]);
System.out.println(list.get(0)[1]);
System.out.println(list.get(0)[2]);
}

好了,asList()方法就学废了。一天学废一个小知识/dog

最新文章

  1. 【译】Core Java Questions and Answers【1-33】
  2. IOS开发之显示微博表情
  3. linux修改mysql密码
  4. leetcode 205
  5. VBA使用的Randomize和DoEvents
  6. Google类VR设备知识
  7. Button 设置适应不同版本 旋转以后大小相应的改变
  8. UIButton之Block回调
  9. 结构体定义 typedef struct 用法详解和用法小结
  10. Java Access Levels(访问控制)
  11. IOC容器在框架中的应用
  12. Python网络爬虫
  13. 关于Unity项目中创建项目遇到的一些问题
  14. 基于Spring的RPC通讯模型.
  15. Spring Boot 2.x :通过 spring-boot-starter-hbase 集成 HBase
  16. 自己写的JdbcUtils小工具-----得到Connection对象
  17. 洛谷 4383 [八省联考2018]林克卡特树lct——树形DP+带权二分
  18. js日期操作,某天的N天后,一个月后的日期
  19. 使用GitHub和Eclipse进行javaEE开发步骤
  20. Angular面试题三

热门文章

  1. SAP 实例 9 Text output
  2. java+mybatis实现一个简单的银行系统,实现存取款与账户查询
  3. tail -f 、tail -F、tailf的区别
  4. golang的超时处理使用技巧
  5. Unity3D学习笔记6——GPU实例化(1)
  6. Linux从root切换某个用户时可能出现:-bash-4.1$
  7. 【跟着大佬学JavaScript】之节流
  8. java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
  9. 匿名对象和private关键字
  10. BACnet MS/TP转MQTT网关金鸽BL103