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 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
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
extends AbstractList
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
list = Arrays.asList(arr);
ArrayList
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
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
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.
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.