装饰器模式用于不修改原始集合前提下动态增强功能,如Collections.synchronizedList()和unmodifiableSet();适配器模式则解决类型不兼容问题,如Arrays.asList()将数组适配为List接口。

Java集合框架中,装饰器模式和适配器模式不是概念堆砌,而是真实落地在日常API里的设计逻辑。它们解决两类不同问题:一个是在不改原始集合的前提下“加功能”,另一个是让“不匹配的类型能一起用”。下面分场景讲清楚。
装饰器模式:给集合动态加能力
装饰器的核心是“包装+同接口+增强行为”。集合工具类 Collections 提供的一系列 synchronizedXxx()、unmodifiableXxx()、checkedXxx() 方法,就是典型应用。
-
同步包装:比如
Collections.synchronizedList(new ArrayList())返回的是SynchronizedList实例,它实现了List接口,内部持有一个原始List引用,在每个方法调用前后自动加锁,而原始ArrayList本身完全没变。 -
只读包装:调用
Collections.unmodifiableSet(new HashSet())得到的是UnmodifiableSet,它拦截所有修改操作(如add、clear),抛出UnsupportedOperationException,但遍历、查询等只读方法照常转发——原始集合仍可被其他引用修改,只是这个“视图”拒绝变更。 - 关键点:这些装饰器类都继承自
SynchronizedCollection或类似基类,遵循统一的“持有被装饰对象 + 实现相同接口 + 拦截并增强”的结构,支持多层嵌套,比如先只读再同步:Collections.synchronizedList(Collections.unmodifiableList(list))。
适配器模式:让数组和集合“说同一种话”
适配器要解决的是“类型不兼容但想共用一套逻辑”的问题。最常见例子就是 Arrays.asList() —— 它把一个普通数组(比如 String[])转成一个 List 接口的实现,让数组能用 contains、indexOf 等集合方法。
- 返回的不是
ArrayList,而是私有静态类Arrays.ArrayList(注意:和java.util.ArrayList同名但不同类),它内部直接持有一个数组引用,所有操作都基于该数组展开,没有复制数据。 - 这个
Arrays.ArrayList就是适配器:目标接口是List,被适配者是原生数组,适配器通过组合(持有数组)+ 实现List接口,完成了“让数组表现得像集合”的转换。 - 限制也很明显:它不支持增删(
add、remove会抛异常),因为数组长度固定;这恰恰说明适配器不做语义强改,只做最小接口对齐。
两者的本质区别一眼看穿
别记定义,记住动作:
- 装饰器 = “我本来就能干这事,现在给你加个锁 / 加个校验 / 加个日志”,接口不变,行为增强;
- 适配器 = “你本来不能干这事,但我帮你‘翻译’一下,让你看起来能干”,接口变了(从数组变成List),目的是连通。
- 代码上,装饰器类通常叫
SynchronizedXXX、UnmodifiableXXX;适配器类往往藏在工具方法里,比如Arrays.ArrayList、Collections$EmptyList,不对外暴露构造器。

















