1. 程式人生 > 實用技巧 >Java中的Arrays.asList()報Exception in thread "main" java.lang.UnsupportedOperationException異常問題

Java中的Arrays.asList()報Exception in thread "main" java.lang.UnsupportedOperationException異常問題

使用用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的其中一個建構函式原始碼: