java推荐面向接口编程,我们一般写函数参数的时候总会选择接口的声明,然后根据接口的方法来进行操作。这里说说list的一个坑。
说起list的实现类,你一定能想到arraylist,linkedlist,还有一些并发安全集合copyonwritearraylist等等,今天说的list就是线程不安全的这些,这些集合基本上通过这个list接口就可以做到所有操作。久而久之给我们一种错觉就是只要符合我的list规范,里面的方法一定被实现好了。下面说一个特例,这个需要人为的去规避。
例子能获取到List的对象也可以通过Arrays的 public static <T> List<T> asList(T... a);这个工具类。这个返回的List就比较有限制了。我们从代码来看。
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
从代码上可以看出是返回了一个arraylist对象,然后集合作为参数传入的。
仔细看就会发现这个ArrayList不是我们印象里的ArrayList,而是Arrays的一个内部类。
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
看类的声明好像没有什么问题,和其他的list的集合没有太多不同。但是里面实现的方法却有点少。只有下面几个。
那么也就是说他本身并没有实现add等操作的方法,那只能从父类AbstractList查找。下面列举几个方法的实现,都很简单。
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
方法的实现全部都是抛出不支持的异常。也就是说如果执行的add等操作得到的结果就是抛出异常。这个错误还是在编译期间不可知的。
java文档中则写了如下的内容:返回一个受指定数组支持的固定大小的列表。换句话说这样方法只是把你的数组包装成了一个List,操作上还是等同你直接使用数组,而且大小也是确定的,并不能做扩容等操作。
结论我们使用接口作为方法的参数没有问题,这同样需要调用的人传入一个常用的集合,例如arraylist,linkedlist。对于其他形式返回出的list请看具体文档描述在操作,因为很可能里面少覆写了方法。对于数组想转换成list也建议使用常见集合的addAll的方法来做一次数据的另存为,虽然这样操作比直接要麻烦一些,但是为后面的操作提供了很大方便。
共同学习,写下你的评论
评论加载中...
作者其他优质文章