collection是java集合框架的顶层能力契约,只定义add、remove、size等通用操作,不提供实现;list在其基础上增强契约,明确要求有序、可重复、支持索引访问;多态通过接口声明实现解耦,运行时由具体类(如arraylist、linkedlist)决定行为,保障灵活性与安全性统一。

多态在Java集合框架中不是语法技巧,而是设计契约的落地方式。Collection作为顶层接口,不提供实现,只定义“能做什么”;List继承它并补充“怎么按顺序做”。用ArrayList实例向上转型为Collection或List,就是靠这套契约让代码既灵活又安全。
Collection是能力契约,不是容器模板
Collection接口本身不能new,它只声明add、remove、size等通用行为。这意味着只要某个类实现了Collection,就承诺支持这些操作——不管它是ArrayList、HashSet还是自定义集合。这种“能力承诺”就是契约的核心。
- 写方法参数时用Collection
,调用方传ArrayList、LinkedList甚至TreeSet都合法 - 返回值类型声明为Collection
,内部可自由切换不同实现,调用方无需感知 - 不能调用List特有方法(如get(0)),因为Collection契约里没规定索引访问
List是增强契约,明确“有序+可重复+可索引”
List在Collection基础上加了三条硬性约定:元素插入顺序必须保留、允许重复、必须支持整数索引操作。这使得List既能当普通集合用,又能当动态数组用。
- add(int index, E element)和get(int index)这类方法只在List中存在,Collection不认可它们
- ArrayList和LinkedList都遵守这个契约,但实现方式完全不同:前者靠数组,后者靠链表
- 用List
list = new ArrayList(),表面是创建对象,本质是签署一份“有序可索引”的协议
多态调用时,方法实际执行取决于运行时类型
声明为Collection或List只是编译期检查,真正执行哪个add、remove逻辑,由new出来的具体类决定。比如clear()在ArrayList中清空数组,在LinkedList中断开所有节点引用。
- Collection
c = new ArrayList(); c.add("a") → 走ArrayList的add - List
l = new LinkedList(); l.add("b") → 走LinkedList的add - 即使c和l都声明为上层接口,各自add内部扩容、内存布局、时间复杂度完全不同
契约越清晰,多态越可靠
Collection和List的分层不是为了多写几行代码,而是把“什么能做”和“什么必须做到”分开定义。开发者按契约写代码,JVM按契约找实现,第三方库按契约提供新实现——整个生态因此解耦。
- 新增一个ConcurrentSkipListSet,只要实现Collection接口,就能无缝接入现有工具方法
- 测试时用Mockito模拟Collection,只需stub add/remove/size,不用管底层结构
- 面试常问“为什么ArrayList不是Collection直接实现类”,答案就是:它必须先履行List契约,再继承Collection能力











