编译器禁止向 list

因为编译器无法确认实际容器能接受哪种具体类型,只允许 null 这个在所有引用类型中都安全的值。
编译器不知道真实类型,只能保守限制
当你声明 List extends Number>,它可能指向 ArrayList<integer></integer>、ArrayList<double></double> 或 ArrayList<biginteger></biginteger>。编译器只知道元素是 Number 的某个子类,但不确定是哪一个。
- 如果实际是
ArrayList<integer></integer>,你 add1.0(Double)就会破坏类型一致性 - 如果实际是
ArrayList<double></double>,你 add42(Integer)同样出错 - 编译器必须阻止所有可能违规的写入,所以禁止除
null外的一切add
null 是唯一无需类型校验的“通用值”
null 不携带任何类型信息,在 Java 中可赋给任意引用类型变量,不会引发类型冲突。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
list.add(null)总是合法:无论底层是ArrayList<string></string>还是LinkedList<number></number>,null都能存入 - 其他值都有明确类型,而通配符上限不提供足够信息让编译器验证其兼容性
这不是缺陷,而是类型安全的设计选择
PECS 原则把“只读”语义编码进类型系统:? extends T 明确表示“这个集合是用来产出 T 或其子类实例的”,不是用来填充的。
- 你要往里加东西,就该用
? super T—— 它告诉编译器“我保证只塞T及其子类” - 混用读写需求?直接用具体类型,比如
List<number></number>或泛型方法<t> void process(List<t> list)</t></t>
本质上,不允许 add 非 null 值,是为了防止运行时类型错误,把问题拦在编译期。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










