Java中的Arrays.asList()報Exception in thread "main" java.lang.UnsupportedOperationException異常問題
阿新 • • 發佈:2020-07-18
使用用Java中的Arrays.asList(...)
獲得一個list後進行後續操作可能會出現 java.lang.UnsupportedOperationException
異常問題
比如以下例子:
public class Test { public static void main(String[] args) { String[] str = {"1","2","3","4"}; List<String> list = Arrays.asList(str); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()){ iterator.next(); iterator.remove(); } } }
上例中通過Arrays.asList(str)
獲得一個list,然後我們利用一個迭代器對其中的元素進行刪除操作,但是改程式碼會報如下錯誤:
為什麼會報這個錯誤呢?
我們來看一下Arrays.asList()
的原始碼就知道了。
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
可以看出該靜態方法實際上幫我們新建了一個ArrayList
,並利用陣列a初始化。目前來講也沒啥問題,那麼我們繼續深入......。去看看這ArrayList
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) { a = Objects.requireNonNull(array); }
1.從上面原始碼中可以看出,Arrays這個工具類實際上自己實現了一個內部類ArrayList
,而不是呼叫我們熟知的java.util.ArrayList
。
2.雖然自己實現的這個內部類繼承和java.util.ArrayList
都是繼承AbstractList
,但是在AbstractList
中的remove、add等方法在AbstractList中是預設throw UnsupportedOperationException
,這時候就需要繼承的子類重寫該方法。
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
throw new UnsupportedOperationException();
}
3.java.util.ArrayList
重寫了這些方法,而Arrays
中自己新建的內部類ArrayList
沒有重寫,所以會丟擲異常。
那麼針對這種情況如何解決呢?可以參考以下方式:
public class Test {
public static void main(String[] args) {
String[] str = {"1","2","3","4"};
List<String> list = new ArrayList<>(Arrays.asList(str));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
iterator.next();
iterator.remove();
}
}
}
可以通過java.util.ArrayList
構造方法直接初始化一個list。因為Arrays.asList(str)
實際上返回了一個集合型別。我們可以想象成,str陣列的每個元素依次彈出到list中,這種形象的比喻。
貼一下java.util.ArrayList
的其中一個建構函式原始碼: