Arrays.asList()返回的是不可变的内部类ArrayList,不支持add/remove等操作,调用会抛出UnsupportedOperationException;基本类型数组需用Stream或Guava转换;集合转数组应使用toArray(T[] a)避免ClassCastException。

Arrays.asList() 为什么不能直接修改集合
Arrays.asList() 返回的不是 java.util.ArrayList,而是 Arrays 的静态内部类 ArrayList(注意:和 java.util.ArrayList 同名但不同类)。它底层直接引用原始数组,不支持 add()、remove()、clear() 等结构性修改操作,调用会抛出 UnsupportedOperationException。
常见错误现象:
String[] arr = {"a", "b"};
List list = Arrays.asList(arr);
list.add("c"); // 运行时抛出 UnsupportedOperationException
- 如需可变集合,必须包装一层:
new ArrayList(Arrays.asList(arr)) - 该方法对基本类型数组(如
int[])无效——它会把整个数组当做一个元素,返回List,而非List - 传入
null会导致NullPointerException
基本类型数组怎么转 List
Java 泛型不支持基本类型,所以 int[]、double[] 等无法直接用 Arrays.asList() 转成 List。必须手动装箱或借助工具类。
- 用 Java 8 Stream(推荐):
int[] arr = {1, 2, 3}; Listlist = Arrays.stream(arr).boxed().collect(Collectors.toList()); - 用 Guava(简洁):
Lists.newArrayList(Ints.asList(arr))(需引入com.google.guava:guava) - 手动循环(兼容老版本):
List
list = new ArrayList<>(); for (int i : arr) list.add(i);
注意:Ints.asList(arr) 返回的是 List 视图,仍不可增删;要可变请再套一层 new ArrayList()。
集合转回数组要注意泛型擦除
List.toArray() 有两个重载:Object[] toArray() 和 T[] toArray(T[] a)。后者才能保留类型信息,否则强转会触发 ClassCastException。
立即学习“Java免费学习笔记(深入)”;
错误写法:
Listlist = Arrays.asList("x", "y"); String[] arr = (String[]) list.toArray(); // 运行时 ClassCastException
- 正确写法(推荐):
String[] arr = list.toArray(new String[0]);(传入空数组,JVM 自动推导类型) - 传入长度不足的数组(如
new String[1]),JVM 会新建一个合适大小的同类型数组返回 - 传入过大数组(如
new String[10]),多余位置会被设为null,且返回的就是该数组本身
性能与场景选择:什么时候该用 Collections.unmodifiableList
如果只是需要「只读视图」避免误改,又不想复制数据,Collections.unmodifiableList(Arrays.asList(arr)) 比新建 ArrayList 更轻量。
- 它不拷贝数组,仅包装一层代理,时间/空间复杂度都是 O(1)
- 所有修改操作(
add、set、clear)都会立即抛出UnsupportedOperationException - 注意:原始数组仍可被外部直接修改(因为底层仍是那个数组),它只拦截集合接口调用
- 若需彻底隔离,必须深拷贝数组:
new ArrayList(Arrays.asList(Arrays.copyOf(arr, arr.length)))
真正容易被忽略的是:unmodifiableList 包装的仍是原始数组引用,不是防御性副本。









