一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Java中 为什么 PECS 原则中的 `

时间:2026-07-21 09:21:50 编辑:袖梨 来源:一聚教程网

编译器禁止向 List<? extends Number> 添加非 null 值以保障类型安全,仅允许 add(null),因为 null 是唯一无需类型校验的通用值;这符合 PECS 原则中“只读”语义的设计。

` 限制了只能 add `null`">

因为编译器无法确认实际容器能接受哪种具体类型,只允许 null 这个在所有引用类型中都安全的值。

编译器不知道真实类型,只能保守限制

当你声明 List<? extends Number>,它可能指向 ArrayList<Integer>ArrayList<Double>ArrayList<BigInteger>。编译器只知道元素是 Number 的某个子类,但不确定是哪一个。

  • 如果实际是 ArrayList<Integer>,你 add 1.0Double)就会破坏类型一致性
  • 如果实际是 ArrayList<Double>,你 add 42Integer)同样出错
  • 编译器必须阻止所有可能违规的写入,所以禁止除 null 外的一切 add

null 是唯一无需类型校验的“通用值”

null 不携带任何类型信息,在 Java 中可赋给任意引用类型变量,不会引发类型冲突。

  • list.add(null) 总是合法:无论底层是 ArrayList<String> 还是 LinkedList<Number>null 都能存入
  • 其他值都有明确类型,而通配符上限不提供足够信息让编译器验证其兼容性

这不是缺陷,而是类型安全的设计选择

PECS 原则把“只读”语义编码进类型系统:? extends T 明确表示“这个集合是用来产出 T 或其子类实例的”,不是用来填充的。

立即学习“Java免费学习笔记(深入)”;

  • 你要往里加东西,就该用 ? super T —— 它告诉编译器“我保证只塞 T 及其子类”
  • 混用读写需求?直接用具体类型,比如 List<Number> 或泛型方法 <T> void process(List<T> list)

本质上,不允许 add 非 null 值,是为了防止运行时类型错误,把问题拦在编译期。

热门栏目