Arrays.asList是典型对象适配器模式,它将数组包装为List视图,支持get/set/size等操作但禁用add/remove,因内部类继承AbstractList且未重写增删方法,修改与数组双向同步,本质是轻量协议转换而非数据复制。

Arrays.asList 是典型的对象适配器模式
它不改变原始数组,也不复制元素,而是创建一个“包装类”(java.util.Arrays.ArrayList),让数组对外呈现出 List 接口的行为。这个内部类实现了 List 接口的大部分方法(如 get、set、size、contains),但刻意未实现 add、remove、clear 等会改变结构的操作——这正是适配器模式中“按需提供能力”的体现。
适配的核心:双向同步与视图语义
该适配器不是独立副本,而是对原数组的实时视图:
- 调用
list.set(i, x)会直接修改数组第i个位置的值 - 修改数组内容(如
arr[0] = "new")后,再访问list.get(0)会立即看到新值 - 这种“同源联动”是适配器轻量高效的关键,也是它被设计为固定大小的原因
为什么不能增删?这是适配边界的设计选择
数组本身长度不可变,而 List.add() 要求扩容能力。适配器不伪造能力,而是明确拒绝越界操作:
- 其内部类继承自
AbstractList,而AbstractList.add()默认抛出UnsupportedOperationException - 这不是缺陷,而是忠于被适配对象(数组)本质的体现——就像电源适配器不会把 220V 变成 380V,它只做协议转换
- 若需可变行为,应显式用
new ArrayList(Arrays.asList(arr))构建新适配器,这是组合使用适配器的常见实践
注意基本类型数组的“假适配”陷阱
Arrays.asList(new int[]{1,2,3}) 不会返回含三个元素的 List<integer></integer>,而是返回仅含一个元素(即整个 int[] 对象)的 List<int></int>:
- 因为泛型不支持基本类型,
asList将int[]当作单个Object参数传入 - 正确做法是先装箱:用
Integer[]数组,或 Java 8+ 的Arrays.stream(arr).boxed().collect(Collectors.toList()) - 这提醒我们:适配器能否正常工作,高度依赖输入是否符合其预期契约

















