Collections.copy 方法体现 PECS 原则:源列表用 ? extends T(生产者,只读),目标列表用 ? super T(消费者,只写),确保类型安全的跨集合元素复制。

Java 的 Collections.copy 方法是 PECS 原则最经典、最直接的实战体现。它不是为了炫技,而是为了解决一个真实痛点:如何在不丢失类型安全的前提下,把一种类型的元素“搬”到另一种兼容类型的集合中。
方法签名暴露了全部意图
public static
这个签名里没有一个字符是多余的:
- src 是 ? extends T → 它只“产出”T 或其子类对象,是纯粹的生产者
- dest 是 ? super T → 它只“接收”T 或其子类对象,是纯粹的消费者
- 两个通配符共同锚定 T → 确保从 src 拿出的每个 item,都能合法放进 dest
为什么不能用 List 替代?
假设写成 copy(List,调用会立刻受限:
-
copy(personList, studentList)就会编译失败——尽管 Student 是 Person 子类,但List并非List的子类型(泛型不变性) - 开发者只能手动 new 一个中间
List,再遍历转换,既啰嗦又低效
而 PECS 让这种父子类集合间的流转变成一行调用,且全程由编译器校验类型安全。
实际能传哪些组合?
只要满足“src 能提供 T,dest 能收下 T”,就合法。常见有效组合包括:
-
copy(new ArrayList→ Student → Person(), new ArrayList ()) -
copy(new ArrayList→ String → Object -
copy(new ArrayList→ File 实现 Serializable(), new ArrayList ()) -
copy(new ArrayList→ Integer → Number(), new ArrayList ())
反过来就不行:copy(new ArrayList 编译报错——Object 不是 String 的子类,src 无法保证产出 String。
底层循环其实非常朴素
源码逻辑本质上就是:
? extends T











