外观
Java 泛型能防什么错?为什么 List<子类> 不是 List<父类>?
标准回答
泛型相当于给容器贴上“允许装什么”的标签,让编译器提前拦住放错类型的操作。List<Car> 不能直接当作 List<Vehicle>,否则别人就可能往里面放一辆不属于 Car 的车辆。
- 泛型类型参数默认不随继承关系自动转换;通配符表达读写边界。
- ? extends T 适合提供 T,? super T 适合接收 T;仍需按具体操作理解。
- 多数类型参数信息在运行时被擦除,不要以为泛型本身能完成所有 JSON 类型识别。
通俗例子
一个方法只需要读取各种传感器,可以接收 List<? extends Sensor>。它知道取出来至少是 Sensor,但不能随便塞进一个 TemperatureSensor,因为调用方传来的也可能是另一种传感器列表。
深入解释
**为什么父子关系不能直接套进列表:**假设 List<Car> 能当 List<Vehicle>,调用方就能往里面放其他 Vehicle;原持有者却以为每个元素都是 Car,类型安全就被破坏。
通配符怎么理解:? extends Sensor 表示某一种 Sensor 子类型的列表,可以按 Sensor 读取,但不知道究竟是哪种子类型,因此不能任意加入另一种 Sensor。
易混淆点
“extends 列表只能读”是帮助理解的简化说法;例如 clear 仍可调用,关键是不能随意加入某个具体子类型。
参考资料
内容来源
- Android · AI Agent 知识手册 · 原条目
job-J04