在 Java 里,**泛型通配符(wildcard)**主要解决的是:
“泛型类型不确定,但又想安全地使用它” 的问题。
通配符只有三种:?、? extends T、? super T。
下面用通俗解释 + 代码说明怎么用。
?:无界通配符(Unbounded Wildcard)我不知道也不关心具体是什么类型,只要是一个泛型就行。
void printList(List<?> list) {
for (Object o : list) {
System.out.println(o);
}
}
✅ 可以接收:
List<String>
List<Integer>
List<Double>
❌ 不能往里加元素(除了 null):
list.add("abc"); // 编译错误
原因:编译器不知道 ? 到底是什么类型。
? extends T:上界通配符(Upper Bounded)类型是 T 或 T 的子类
void printNumbers(List<? extends Number> list) {
for (Number n : list) {
System.out.println(n);
}
}
✅ 可以接收:
List<Integer>
List<Double>
List<Number>
❌ 不能添加元素:
list.add(1); // 编译错误
原因:
? extends Number 可能是 List<Integer>,也可能是 List<Double>,
加 Integer 不安全。
✅ 适合读取,不适合写入
? super T:下界通配符(Lower Bounded)类型是 T 或 T 的父类
void addNumbers(List<? super Integer> list) {
list.add(1);
list.add(2);
}
✅ 可以接收:
List<Integer>
List<Number>
List<Object>
❌ 读取时只能当 Object:
Object o = list.get(0); // 只能这样
原因:
编译器只知道下限是 Integer,但不知道具体是什么父类。
✅ 适合写入,不适合读取
Producer → Extends,Consumer → Super
| 场景 | 用哪个 |
|---|---|
| 只往外取(生产者) | ? extends T |
| 只往里放(消费者) | ? super T |
| 又取又放 | 不用通配符,用具体泛型 |
public static <T> void copy(
List<? super T> dest,
List<? extends T> src
) {
for (int i = 0; i < src.size(); i++) {
dest.set(i, src.get(i));
}
}
src:生产者 → extendsdest:消费者 → super✅ 如果只是使用泛型,不关心类型参数
void print(List<?> list)
✅ 需要返回具体类型或类型之间有约束
<T> T getFirst(List<T> list) {
return list.get(0);
}
?:啥都行,只能读? extends T:只读(生产者)? super T:只写(消费者)如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。