Collections.emptyList() 与 Arrays.asList()是开发常用类库中的两个方法,一般是作为方法default返回值或者循环中使用的。这两个方法有一个需要注意的地方,我们首先来看一个例子:

上面的代码运行结果是抛出异常:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at com.zhengyu.demo.Application.main(Application.java:16)
也就是说Collections.emptyList()返回的List对象,在使用add方法时会产生异常,我们来看看emptyList方法的源码。


看到上面的immutable注释应该就明白了,是不可变集合。guava当中有很多immutable的api,还有一些多线程设计模式中有不变模式,或者一些防御性拷贝。
继续看这个EmptyList类源码

可以看到这个EmptyList是Collections里面的一个静态内部类,只继承了AbstractList抽象类,只实现了RandomAccess(随机访问优化标识)、Serializable接口(系列化)。
看到这里应该就懂了,AbstractList的add实现是直接抛异常,所以就注定这个empryList不支持add操作。也不支持get操作。
看一下AbstractList中的add方法


我们继续看一下Arrays.asList方法源码

可以看到跟Collections.emptyList是类似的,都是内部类
Array.asList()返回的ArrayList不是java.util.ArrayList,而是Arrays类中的静态内部类,也是直接继承AbstractList,并没有实现List接口,所以也是不支持add、get的。如果你使用了add get等方法,就会抛出java.lang.UnsupportedOperationException。
总结:
在Collections.emptyList & Arrays.asList()使用中需要注意,返回的List是不可变集合,建议只做一些默认值返回,只做循环操作,不要做修改操作。另外创建集合推荐guava的方式,比较符合Effective java提倡的静态方法创建对象。
如下:
Lists.newArrayList();
Lists.newArrayListWithCapacity(16);
网友评论