Avoiding the Fixed‑Size List Pitfall of Arrays.asList in Java
This article explains why using Arrays.asList to convert an array into a List can produce an immutable, fixed‑size list that throws UnsupportedOperationException on add or remove operations, illustrates the issue with real‑world incident details, analyzes the internal implementation, and provides a safe replacement using java.util.ArrayList.
In Java development, converting arrays to collections is common, and many developers reach for Arrays.asList() because of its concise syntax. However, the method returns a fixed‑size list backed by the original array, and attempts to modify it (e.g., add or remove) result in an UnsupportedOperationException, which can cause serious production incidents.
Incident Review : While building an e‑commerce order system, a developer used Arrays.asList() to create a List<Integer> from an Integer[]. Adding a new order ID to the list triggered an UnsupportedOperationException, halting the order processing flow and causing user‑experience degradation, business interruption, financial loss, and trust issues.
Problem Description :
Integer[] arr = {1, 2};
List<Integer> list = Arrays.asList(arr);
list.add(3); // throws UnsupportedOperationExceptionThe exception occurs because Arrays.asList(arr) returns an internal static class ArrayList (not java.util.ArrayList) that extends AbstractList and does not implement add or remove. Those methods inherit the default implementation from AbstractList, which simply throws UnsupportedOperationException.
Internal Implementation (excerpt):
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable {
private final E[] a;
ArrayList(E[] array) { a = Objects.requireNonNull(array); }
public int size() { return a.length; }
public E get(int index) { return a[index]; }
// No add/remove implementation – inherited from AbstractList
}Because the internal ArrayList lacks mutable operations, any call to list.add(...) or list.remove(...) propagates to AbstractList.add, which throws the exception.
Solution : Wrap the fixed‑size list with a real mutable java.util.ArrayList before performing modifications.
Integer[] arr = {1, 2};
List<Integer> list = Arrays.asList(arr);
ArrayList<Integer> mutableList = new ArrayList<>(list);
mutableList.add(3); // works
mutableList.remove(1); // worksComplete demo:
public class Arrays_BugDemo {
public static void main(String[] args) {
Integer[] arr = {1, 2};
List<Integer> list = Arrays.asList(arr);
// This will fail
try { list.add(3); } catch (UnsupportedOperationException e) {
System.out.println("list.add(3) error: " + e.getMessage());
}
// Use mutable ArrayList
ArrayList<Integer> arrayList = new ArrayList<>(Arrays.asList(arr));
arrayList.add(3);
arrayList.forEach(System.out::println);
}
}Running the program prints the elements 1, 2, 3, confirming that the mutable list works correctly.
Conclusion : Arrays.asList() should only be used when a fixed‑size view of the original array is required. For any scenario that needs element addition or removal, create a new java.util.ArrayList (or another mutable collection) from the result of Arrays.asList(). This practice prevents runtime crashes and improves code robustness.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
