list

读取安全:所有子类都能向上转型为 Number
声明 List extends Number> 表示这个集合实际装的是某个**确定但未知的** Number 子类型,比如 Integer、Double 或 BigDecimal。无论具体是哪一种,它们都继承自 Number,所以调用 get() 返回的值一定能安全赋给 Number 类型变量:
-
Number n = list.get(0);—— 合法,因为Integer、Double等都是Number的子类 - 你可以直接调用
n.doubleValue()、n.toString()等Number定义的方法,无需强转
写入禁止:编译器无法验证添加值是否匹配底层真实类型
你写 list.add(new Integer(42)) 时,编译器必须保证该操作对所有可能的实际类型都成立。但它知道这个引用可能指向:
-
ArrayList<double></double>→ 加Integer会破坏类型一致性 -
LinkedList<bigdecimal></bigdecimal>→ 加Integer同样不合法 - 哪怕你心里清楚它其实是
ArrayList<integer></integer>,编译器也只看声明,不看运行时实例
只要存在一种可能失败的情形,编译就拒绝——这是 Java 泛型“类型安全优先”原则的体现。
null 是唯一允许的写入值
null 不携带任何类型信息,可赋值给任意引用类型,不会引发类型冲突:
-
list.add(null);—— 编译通过 - 但这只是语法特例,不能替代业务上的写入需求
正确选型:按读写意图选择泛型形式
不要为了“看起来通用”而滥用 ? extends T。它本质是“只读视图”,适合做方法参数:
- ✅
void printNumbers(List extends Number> src)—— 只读场景,安全又灵活 - ✅
List<number> numbers = new ArrayList();</number>—— 需要存多种数字子类时,用具体上界类型 - ❌
List extends Number> list = new ArrayList();—— 自己新建却还想add,逻辑矛盾
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











