ArrayList结合泛型通配符的核心目的是让方法安全接收多种具体类型的ArrayList而不破坏类型安全;通配符?用于形参表示任意类型,仅支持读取(元素视为Object)且禁止add非null值;? extends限定上界以支持按公共父类读取;? super限定下界以支持向更宽泛类型集合写入。

ArrayList 结合泛型通配符的核心目的,是让方法能安全接收多种具体类型的 ArrayList(比如 ArrayList、ArrayList),而不破坏类型安全。关键在于:通配符 ? 用在形参位置,不是用来创建对象,也不参与返回值或赋值操作。
通配符用于方法参数最常见
当一个方法只需读取集合内容、不修改或不依赖具体类型时,用 ArrayList> 最直接:
- 声明形参为
ArrayList>,表示“接受任意元素类型的 ArrayList” - 方法体内只能把元素当作
Object处理(因为编译器不知道 ? 到底是什么) - 不能调用
add()等写入方法(除null外),否则编译报错
示例:
public static void printAll(ArrayList> list) {
for (Object item : list) { // 只能用 Object 接收
System.out.println(item);
}
// list.add("x"); // ❌ 编译错误:无法确定添加的类型是否兼容 ?
}
用 extends 限定读取范围(上界)
如果方法逻辑依赖某个公共父类或接口(比如所有元素都能转成字符串),可用 ? extends Number 或 ? extends CharSequence:
-
ArrayList extends Number>可接收ArrayList、ArrayList等 - 仍不能往里
add()具体数值(除了null),但可以安全地get()并当作Number使用 - 适合统计、格式化、只读遍历等场景
示例:
public static double sumNumbers(ArrayList extends Number> list) {
double sum = 0.0;
for (Number n : list) { // ✅ 可以按 Number 处理
sum += n.doubleValue();
}
return sum;
}
用 super 限定写入能力(下界)
当方法主要向集合添加数据,且希望兼容更宽泛的接收类型时,用 ? super Integer:
-
ArrayList super Integer>可接收ArrayList、ArrayList、ArrayList - 可以安全调用
add(new Integer(42))(因为 Integer 是所有这些类型的子类) - 但
get()返回的是Object,需谨慎转型 - 适合工具类中“填充集合”的方法
示例:
public static void addInts(ArrayList super Integer> list) {
list.add(100); // ✅ 安全:Integer 可放进 Integer/Number/Object 类型的列表
list.add(200);
// Integer x = list.get(0); // ❌ 不安全:get() 返回 Object,不能直接赋给 Integer
}
实际调用时注意类型匹配
通配符解决的是“多态传参”问题,但 Java 泛型本身不具备继承性:
-
ArrayList不是ArrayList的子类 - 所以不能直接把
ArrayList传给形参为ArrayList的方法 - 但可以传给
ArrayList>或ArrayList extends Object>(二者等价)
一句话总结:通配符不是为了绕过类型检查,而是用更精确的约束替代硬编码类型,让方法既灵活又安全。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











