Arrays.asList gotchas in Java
Fixed-size, backed by the array, add() throws UnsupportedOperationException.
Arrays.asList("a", "b") gives you something that says it's a List and even prints like one. Then you call add() and it throws. What did you actually get?A list-shaped window on an array
**Arrays.asList wraps an array in a List view. An array can't grow, so the list is fixed-size**: set() works, but **add() and remove() throw UnsupportedOperationException**. It's not a java.util.ArrayList either, but a private class with the same simple name.
List<String> l = Arrays.asList("a", "b");
l.set(0, "z"); // ok: [z, b]
l.add("c"); // UnsupportedOperationExceptionYour turn
What happens?
List<String> l = Arrays.asList("p", "q");
l.remove(0);
System.out.println(l);Prints [q]Prints [p, q]Throws UnsupportedOperationException
Show the answer
Removing would shrink the backing array, which is impossible. **remove throws UnsupportedOperationException** at runtime, just like add.
Writes go both ways
The list and the array share the same storage. list.set changes the array, and writing to the array shows up in the list.
String[] arr = {"a", "b"};
List<String> list = Arrays.asList(arr);
list.set(0, "z"); // arr[0] is now "z"
arr[1] = "q"; // list.get(1) is "q"Both directions
What does this print?
String[] arr = {"a", "b"};
var list = Arrays.asList(arr);
arr[0] = "X";
list.set(1, "Y");
String a = Arrays.toString(arr);
System.out.println(list + " " + a);[X, Y] [X, Y][a, Y] [X, b][X, b] [a, Y]
Show the answer
One shared storage: the array write and the list write both land in the same place, so both print [X, Y].
The primitive array trap
Generics can't hold primitives, so T can't be int. With an int[], **T becomes int[] and you get a List<int[]> with ONE element**: the array itself. Use Integer[], or Arrays.stream(nums).boxed().toList().
int[] nums = {1, 2, 3};
Arrays.asList(nums).size(); // 1, not 3!Need a list you can grow?
var l = Arrays.asList("a", "b");
l.add("c"); // throws
var a = (ArrayList<String>) l; // CCEFixed-size, and the cast fails with ClassCastException: it isn't a java.util.ArrayList.
var l = new ArrayList<>(
Arrays.asList("a", "b"));
l.add("c"); // [a, b, c]Copy into a real ArrayList. (List.of won't help: it's immutable.)
Where it bites
Arrays.asList is great for quick fixed lists in tests and for passing an array to an API that wants a List. Bugs appear when that list travels to code that tries to add to it, and the exception fires far from where the list was made.
Key takeaways
- Fixed size: add/remove throw UnsupportedOperationException
- set() writes through to the array, and array writes show in the list
- Arrays.asList(intArray) gives a List<int[]> of size 1
- Need a growable copy? new ArrayList<>(Arrays.asList(...))
💡 Arrays.asList puts a List-shaped frame around an existing array — you can repaint the pictures, but you can't add more slots to the frame.
Print Arrays.asList("a").getClass() and you'll see class java.util.Arrays$ArrayList: a private nested class that shares its simple name with the real ArrayList, which confuses plenty of developers.
Practice questions
What happens when this runs?
List<String> list = Arrays.asList("a", "b");
list.add("c");
System.out.println(list);- [a, b, c]
- Throws UnsupportedOperationException
- [a, b]
- Compile error
Check your answer
Throws UnsupportedOperationException. The list is fixed-size because it's backed by an array, which can't grow. add() throws at runtime.
What does this print?
String[] arr = {"a", "b", "c"};
List<String> list = Arrays.asList(arr);
list.set(0, "z");
arr[2] = "q";
System.out.println(Arrays.toString(arr) + list);- [z, b, q][z, b, q]
- [a, b, q][z, b, c]
- [z, b, c][z, b, q]
- [a, b, c][z, b, c]
Check your answer
[z, b, q][z, b, q]. The list and the array share the same storage. list.set changes the array and the array assignment shows up in the list.