Arrays.asList的源码分析

以前一直很奇怪为什么Arrays.asList的数组不能插入新的数据,后来看了源码发现是因为内部是一个final的数组支持起来的Arraylist,下面贴入源码与分析。

1.先看Arrays的方法

我们看到Arrays.aslist 返回一个new ArrayList<>(a);

    @SafeVarargs
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

2.我们按住ctrl点击这个ArrayList

发现这个ArrayList不是java.util中的Arraylist而是在Arrays这个类中的一个私有静态类并且继承了AbstractList,

这个类中的set和get方法其实是基于private final E[] a 这个泛型数组的;

   private static class ArrayList<E> extends AbstractList<E> //私有静态类
        implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;   //这个泛型数组支持起这个静态类
ArrayList(E[] array) { //构造器传入一个数组 if (array==null) throw new NullPointerException(); a = array; } public E get(int index) {//得到数组中的值 return a[index]; } public E set(int index, E element) {//替换数组中的值 E oldValue = a[index]; a[index] = element; return oldValue; }
    ......... }

3.等等我们并没有看到add和remove方法呀。淡定,按住ctrl点击这个AbstractList,既然子类中没有方法体,那一定是在父类中实现的

我们发现在父类中,这2个方法都是会抛出异常的(这些会抛出异常的方法称为可选操作)。所以才不能使用这2个方法。但是其实想想为什么要这样子设计呢。为什么不直接设计成抽象的方法呢,为什么要抛出异常呢。

我们要知道会有很多类继承这个AbstractList,有些方法对于有些类是没有意义的,就比如说我们上面这个基于数组的ArrayList,既然基于数组我是必然不能改变数组的大小(数组大小固定),所以所有的会改变数组大小的方法都会抛出UnsupportedOperationException()这个异常。这些没有意义的方法我就没有必要重写,如果变成抽象方法的话重写会很繁琐。并且事先给定了各种接口可以防止继承类接口膨胀,因为继承类可以随意的创造自己的方法而不受约束,但是事先给定了可选操作,就会重写可选操作,使容器类的使用变得轻松

    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

    public E remove(int index) {
        throw new UnsupportedOperationException();
    }

4.如果希望list可以添加删除

可以把Arrays.asList()作为Arraylist的参数传入就像下面这样子

    new ArrayList<>(Arrays.asList("1","2"));

以上均只是个人看法,如有不准确的地方,欢迎大家一起讨论Haha

上一篇:Handler没法取出消息队列中的数据的一个原因


下一篇:windows下运行Eigen