Arrays工具类提供了一个方法asList, 使用该方法可以将一个变长参数或者数组转换成List

其源代码如下:

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

  

问题发现

根据上述方法的描述,我们先来编写几个例子:

public class ArrayExample {
 
 public static void main(String[] args) {
  
  /**使用变长参数*/
  List<String> array1 = Arrays.asList("Welcome", "to","Java", "world");
  System.out.println(array1);
  
  /**使用数组*/
  List<String> array2 = Arrays.asList(new String[] {"Welcome", "to","Java", "world"});
  System.out.println(array2);
 }

}

 运行上述程序,输出如下内容。

[Welcome, to, Java, world]
[Welcome, to, Java, world]

 

心血来潮,突然想在创建的列表中添加一个字符串“Cool~~~”,  走一个。

 /**使用变长参数*/
  List<String> array1 = Arrays.asList("Welcome", "to","Java", "world");
  array1.add("Cool~~~");

  

结果,遇到一个UnsupportedOperationException异常:

Exception in thread "main" java.lang.UnsupportedOperationException
 at java.util.AbstractList.add(Unknown Source)
 at java.util.AbstractList.add(Unknown Source)
 at test.ArrayExample.main(ArrayExample.java:36)

  

不可思议,new ArrayList<>(a)产生的列表调用add方法,竟然遇到问题。

原因查找

那么问题来了,到底发生了什么事情?带着疑问,去查看一下Arrays.asList中使用的ArrayList到底长啥样?

原来Arrays的asList方法使用的ArrayList类是一个内部定义的类,而不是java.util.ArrayList类。

其源代码如下:

 1  /**
 2    * @serial include
 3    */
 4   private static class ArrayList<E> extends AbstractList<E>
 5     implements RandomAccess, java.io.Serializable
 6   {
 7     private static final long serialVersionUID = -2764017481108945198L;
 8     private final E[] a;
 9 
10     ArrayList(E[] array) {
11       if (array==null)
12         throw new NullPointerException();
13       a = array;
14     }
15 
16     public int size() {
17       return a.length;
18     }
19 
20     public Object[] toArray() {
21       return a.clone();
22     }
23 
24     public <T> T[] toArray(T[] a) {
25       int size = size();
26       if (a.length < size)
27         return Arrays.copyOf(this.a, size,
28                    (Class<? extends T[]>) a.getClass());
29       System.arraycopy(this.a, 0, a, 0, size);
30       if (a.length > size)
31         a[size] = null;
32       return a;
33     }
34 
35     public E get(int index) {
36       return a[index];
37     }
38 
39     public E set(int index, E element) {
40       E oldValue = a[index];
41       a[index] = element;
42       return oldValue;
43     }
44 
45     public int indexOf(Object o) {
46       if (o==null) {
47         for (int i=0; i<a.length; i++)
48           if (a[i]==null)
49             return i;
50       } else {
51         for (int i=0; i<a.length; i++)
52           if (o.equals(a[i]))
53             return i;
54       }
55       return -1;
56     }
57 
58     public boolean contains(Object o) {
59       return indexOf(o) != -1;
60     }
61   }
View Code

相关文章: