Arrays.aslist() and UnsupportedOperationException
UnsupportedOperationException
is a member of Java Collection Framework, it’s thrown when an operation cannot be performed because it is not supported for that particular collection.
One of the most common causes for this exception is using the Arrays.asList() method, Let’s dive into the source codes and figure out why this could happen.
Exception Example
List<Integer> list1 = Arrays.asList(1,2,3,4,5);
list1.set(0, 10); // ok, override the first value of list1 with 10
list1.remove(0); // throw UnsupportedOperationException
list1.add(6); // throw UnsupportedOperationException
As the codes shown above, the list element value can be edited, but adding new element to the list, or removing elements from list are not allowed.
Secret in the Source Code
From the source code of Arrays.asList(), we know that it simply returns an ArrayList
, it is strange that neither add()
nor remve()
operation are not allowed.
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
If we check it carefully, we will find that the ArrayList
here is different from java.util.ArrayList
we normally used. The ArrayList
returned by Array.asList()
is of type java.util.Arrays.ArrayList
, it is an inner class of java.util.Arrays
.
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable
{
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
// other fields and methods
}
java.util.Arrays.ArrayList
is actually a fixed size array, The reasons for this judgement are:
- First, it uses a generic array to hold the elements, not a java collection such as List or Set.
- Second, there is no machanism to change the length of internal array, unlike what’s in
java.util.ArrayList
.
The length of array cannot be changed, this is the design intention of Arrays.asList()
why we get UnsupportedOperationException
while calling add
or remove
methods. But where is the exception being thrown?
In the declaration of java.util.AbstractList
, which is the parent class of java.util.Arrays.ArrayList
, both add
and remove
method thrown UnsupportedOperationException
directly, this is where the exception being thrown.
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();
}
How to Resolve UnsupportedOperationException
The List returned by the Arrays.asList() method can be passed to a new java.util.ArrayList
object, which can be modified:
List<Integer> list1 = Arrays.asList(1,2,3,4,5);
List<Integer> list2 = new ArrayList<>(list1);
// or one line
List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,5));
Here, a new java.util.ArrayList
object with list returned from the Arrays.asList() method. When a new element is added to or removed from the ArrayList, it works as expected and the UnsupportedOperationException
will never be thrown.
Conclusion
From this article, we know that Arrays.asList()
returns a fixed-size list, which is actually backed by a specified array. There is no machinasm to change the length of this array, so add
or remove
operation are not allowed.