This is a simple note for myself. I faced an java.lang.UnsupportedOperationException because Arrays.asList(T…) returns unmodifiable collection.
Arrays.asList(T…)
will return a ArrayList… it looks good, but this ArrayList is an inner class with the name of “ArrayList”, it’s not the Android ArrayList that supports add, remove and other operations.
public class Arrays {
....
public static <T> List<T> asList(T… array) {
// This ArrayList is not Android framework's ArrayList
return new ArrayList<T>(array);
}
}
What is the ArrayList from Arrays.asList(T…)?
It is an inner class which extends abstract class AbstractList but not override any remove() or add() methods.
public class Arrays {
private static class ArrayList<E> extends AbstractList<E> implements List<E>, Serializable, RandomAccess {
....
private final E[] a; ArrayList(E[] storage) {
....
} @Override
public boolean contains(Object object) {
if (object != null) {
for (E element : a) {
if (object.equals(element)) {
return true;
}
}
} else {
for (E element : a) {
if (element == null) {
return true;
}
}
}
return false;
} @Override
public E get(int location) {
try {
return a[location];
} catch (ArrayIndexOutOfBoundsException e) {
throw throwIndexOutOfBoundsException();
}
} @Override public int indexOf(Object object) {
if (object != null) {
for (int i = 0; i < a.length; i++) {
if (object.equals(a[i])) {
return i;
}
}
} else {
for (int i = 0; i < a.length; i++) {
if (a[i] == null) {
return i;
}
}
}
return -1;
} @Override public int lastIndexOf(Object object) {
....
} @Override public E set(int location, E object) {
E result = a[location];
a[location] = object;
return result;
} @Override public int size() { return a.length; } @Override public Object[] toArray() { return a.clone(); } @Override
public <T> T[] toArray(T[] contents) {
.....
}
}
....
}
This abstract AbstractList implements java.util.List, but throws UnsupportedOperationException at its remove() and add(), that means any class extends AbstractList without overriding remove or add methods will throw exception as default.
public abstract class AbstractList<E> implements List<E> {
public E remove(int location) {
throw new UnsupportedOperationException();
}
public E set(int location, E object) {
throw new UnsupportedOperationException();
}
}
In a conclusion, Arrays.asList(T…) returns a container which remove and add method will throw exception directly, just the container’s class name is the same as ArrayList from android framework.