title: Arrays.asList()使用中遇到的問題
date: 2020-04-17 14:08:37
categories:java
tags:
概述
Arrays
是java.util包中提供的工具類,主要用于對數組進行各種操作
Arrays.asList()
是該類中提供的一個靜态方法,根據源碼注釋,作用為基于特定數組傳回一個固定大小的清單
Returns a fixed-size list backed by the specified array
問題
運作如下代碼時出現異常:
String[] strs={"str1","str2","str3","str4"};
List<String> arr=Arrays.asList(strs);
arr.add("str5");//抛出異常java.lang.UnsupportedOperationException
arr.remove("str1");//抛出異常java.lang.UnsupportedOperationException
System.out.println(arr);
這裡通過Arrays.asList()将String數組轉化為List,但對List進行add和remove操作時卻報異常
UnsupportedOperationException
,這是為啥呢,為什麼操作不支援呢?
根據上述概述,該方法傳回一個
fixed-size
,即大小不能改變的清單,該方法的源碼很簡單,
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
由源碼可知,該方法傳回一個
ArrayList
,那為啥
ArrayList
就不支援add和remove操作了呢?
原來,這裡的
ArrayList
并不是java.util包中的集合類
ArrayList
,而是在
Arrays
類中自定義的一個内部類,其類的定義源碼就在
asList()
方法源碼下;
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-SlsXF0hb-1589178740353)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420144009.png)]
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-8x6YuRxF-1589178740354)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420144148.png)]
(話說為啥不換個名)
該内部類源碼為
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
//内部源碼省略
....
....
}
可以看到該類繼承了
AbstractList
類,并實作了
RandomAccess
和
Serializable
接口;該類源碼中沒有定義add,remove方法
進一步檢視
AbstractList
類源碼
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
//部分源碼省略
...
...
public boolean add(E e) {
add(size(), e);
return true;
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
//部分源碼省略
...
...
}
可以看到,該類繼承
AbstraceCollection
類并實作
List
接口,執行add,remove操作時均抛出
UnsupportedOperationException
異常;
事實上,檢視
AbstraceList
類其餘源碼可以看到,其中set方法也抛出
UnsupportedOperationException
異常,但ArrayList内部類重寫了set方法,是以可以執行set操作
注意:
- 執行set操作時,如下代碼,分别對數組和由數組轉化的List集合元素進行修改
public static void main(String[] args) {
String[] strs={"str1","str2","str3","str4"};
List<String> list=Arrays.asList(strs);
System.out.println(Arrays.toString(strs));
System.out.println(list);
strs[0]="str1_new";//對strs進行修改
list.set(1,"str2_new");//對list進行修改
System.out.println(Arrays.toString(strs));
System.out.println(list);
}
結果如下:
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-sSor2LLL-1589178740356)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420151851.png)]
發現對數組進行的修改影響到了集合,對于集合進行的修改也影響到了數組;
這是因為
asList()
轉化得到的集合元素直接引用了數組,數組和集合的變化會同步,這同時可能會導緻一些編碼上的問題
-
方法不可操作基本資料類型;因為由于通過new建立一個Arrays.ArrayList時,其參數為可變長泛型,而基本類型是無法泛型化的asList()