编译器禁止向 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.0(Double)就会破坏类型一致性ArrayList<Double>,你 add 42(Integer)同样出错null 外的一切 add
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 值,是为了防止运行时类型错误,把问题拦在编译期。