无界通配符?支持任意类型赋值但仅可读(返回object)、不可写(除null);? extends t支持安全读取为t及其子类、不可写;? super t支持安全写入t及其子类、读取仅得object。

问号(?)本身是无界通配符,表示“任意具体类型”,但它不提供类型安全的写入能力;而有限制通配符(? extends T 和 ? super T)则在读或写操作上做了明确约束,分别服务于“只读”和“只写”场景。
无界通配符 ?:只能读,不能写(除 null 外)
它是最宽松的通配符,适用于完全不关心元素类型、仅需遍历或获取元素的场景。
- 声明形式:
List>、Collection> - 可以接收
List<string></string>、List<integer></integer>、List<object></object>等任意泛型列表 - 能调用
get(int),但返回值类型是Object(因为编译器只知道是“某个未知类型”,而所有引用类型都继承自 Object) - 不能调用
add(E)—— 编译器无法验证你传入的对象是否匹配那个未知类型,所以除null外一律拒绝
上限通配符 ? extends T:侧重“安全读取”,类型可缩小
它限定通配符代表的类型必须是 T 或其子类,常用于从集合中读取统一父类型的数据。
- 声明形式:
List extends Number>可接受List<integer></integer>、List<double></double>、List<number></number> - 能安全地把每个元素当作
Number来用(例如调用doubleValue()) - 依然不能
add(...)任何对象(包括new Integer(1)),因为编译器不知道实际是Integer还是Double,加错类型会破坏类型安全 - 例外:仍可添加
null
下限通配符 ? super T:侧重“安全写入”,类型可扩大
它限定通配符代表的类型必须是 T 或其父类,适合向集合中批量插入某类对象。
- 声明形式:
List super Integer>可接受List<integer></integer>、List<number></number>、List<object></object> - 可以安全地
add(new Integer(42))或add(new Long(100))?不行 —— 只能加Integer及其子类(如AtomicInteger),因为Long不是Integer的子类 - 但不能安全地把
get(0)当作Integer用,返回值类型只能是Object(因可能是List<object></object>)
一句话总结三者核心差异
?:什么都能装进来(指变量赋值),但什么都不能往里塞(指 add);
? extends T:能往外拿 T 类型的东西,但不能往里塞(不确定具体子类);
? super T:能往里塞 T 类型的东西,但往外拿只能当 Object 用(不确定具体父类)。










