这个是在写项目的时候发现的,然后就分析了一下源码,得其内部原理
复现代码示例:
public class ArraysAsList {public static void main(String[] args) {Integer[] array = {1, 2, 3, 4, 5};List<Integer> list = Arrays.asList(array);list.forEach(System.out::println);list.add(11);}
}
程序运行至list.add(11)时报错
Exception in thread "main" java.lang.UnsupportedOperationException
分析源码:
点击查看Arrays.asList源码,静态的返回 List
看一下asList里面 new ArrayList的代码实现,就会发现这里的ArrayList并不是java.util.ArrayList中的单列集合,而是Arrays工具类(java.util.Arrays)中的静态内部类ArrayList
然后回归到Arrays.asList()方法,为什么这个方法生成的List集合无法在add和remove
因为这里返回的是一个 final 数组,数组本身就是不可变的,所以当调用Arrays.asList方法返回一个集合后,无法在对这个集合进行一些操作,这个是数组的特性
private final E[] a;ArrayList(E[] array) {a = Objects.requireNonNull(array);
}
至于为什么java.util包下的ArrayList的底层也是数组,但是它依然可以去add和remove,那是因为它的add和remove方法copy了新的数组,但是在Arrays下面的ArrayList静态内部类中,它并没有实现add和remove方法用来对集合进行添加和删除,如下所示:
也就是说我们可以调用get方法得到Arrays.asList返回的集合元素,也可以set修改这里面的值,但是因为它没有add和remove方法所以无法对集合进行增加和删除,这也是为什么会报错:UnsupportedOperationException(没有支持的方法)的原因。
至此我认为Arrays.asList的问题就讲完了,但是在写这个示例的时候我发现了一个新的知识函数式接口,之前了解过,但是不是很熟悉。
如果你是为了明白Arrays.asList的问题,那么到这里就可以止步了。