Why Arrays.asList and subList Can Throw Unexpected Exceptions in Java
This article explains the hidden pitfalls of Java's Arrays.asList and ArrayList.subList methods, showing how fixed‑size lists cause UnsupportedOperationException, how subList creates a mutable view that can trigger ConcurrentModificationException, and provides concrete code examples and source‑code analysis.
1. Using Arrays.asList – pitfalls
First, the article demonstrates the basic usage of Arrays.asList:
List<Integer> statusList = Arrays.asList(1, 2);
System.out.println(statusList);
System.out.println(statusList.contains(1));
System.out.println(statusList.contains(3));The output shows the list contains the two elements and the contains checks work as expected.
When trying to add an element:
statusList.add(3);
System.out.println(statusList.contains(3));The expected result would be true, but a java.lang.UnsupportedOperationException is thrown.
Reason analysis: Arrays.asList returns an internal fixed‑size ArrayList implementation (an inner class of java.util.Arrays) that overrides many methods such as contains but does not override add. Therefore, any modification method (add, remove, clear) throws UnsupportedOperationException.
Using the utility class Arrays.asList() to convert an array to a collection, you must not use its modification methods; add / remove / clear will throw UnsupportedOperationException .
Hence, when using Arrays.asList, avoid calling mutating methods.
2. Using ArrayList.subList – precautions
Simple subList usage:
List<String> bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");
List<String> luyaoBookList = bookList.subList(3, 5);
System.out.println(bookList);
System.out.println(luyaoBookList);The result shows that luyaoBookList contains the elements at indices 3 (inclusive) to 5 (exclusive) of the original list.
2.1 Modifying original list values affects sublist
bookList.set(3, "路遥-人生");
System.out.println(bookList);
System.out.println(luyaoBookList);After changing the value at index 3 of the original list, the sublist reflects the change because it is a view of the same underlying data.
2.2 Structural modification of original list triggers ConcurrentModificationException
bookList.add("早晨从中午开始");
System.out.println(bookList);
System.out.println(luyaoBookList);Adding an element to the original list changes its structure. When the sublist is later accessed, a java.util.ConcurrentModificationException is thrown.
2.3 Modifying sublist values affects original list
luyaoBookList.set(1, "路遥-平凡的世界");
System.out.println(bookList);
System.out.println(luyaoBookList);Changing an element in the sublist also updates the corresponding element in the original list.
2.4 Structural modification of sublist affects original list
luyaoBookList.add("早晨从中午开始");
System.out.println(bookList);
System.out.println(luyaoBookList);Adding an element to the sublist modifies the original list as well, because the sublist is backed by the same data structure.
2.5 Reason analysis
The Javadoc of subList states that it returns a view of the portion of the list between fromIndex (inclusive) and toIndex (exclusive). The source code shows:
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}The SubList class is an inner class of ArrayList. Its constructor does not create a new independent list; it merely holds a reference to the original list. Therefore, any non‑structural change (e.g., set) to either the original list or the sublist is reflected in the other. Structural changes (add/remove) invalidate the sublist’s internal state, causing a ConcurrentModificationException when the sublist is accessed.
Conclusion
Arrays.asListshould be used only for read‑only or fixed‑size scenarios; avoid calling mutating methods. ArrayList.subList returns a live view of the original list, so non‑structural modifications affect both lists, while structural modifications can lead to ConcurrentModificationException. Understanding these behaviors prevents subtle bugs and runtime exceptions.
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.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
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.
