Java泛型中的通配符

最近想学学集合框架的源代码,结果画风是这样的:

boolean addAll(Collection<? extends E> c);
default boolean removeIf(Predicate<? super E> filter) {
    ...
}
boolean containsAll(Collection<?> c);

一下就暴露了泛型没好好学的锅= =,今天总结一下。


下文统一使用这两个类进行说明。

class Fruit {}
class Apple extends Fruit {}

泛型中的通配符

上边界限定通配符

用法:<? extends Fruit>

即当前类型 X = ? extends Fruit,类似X <= Fruit的感觉

这个X类型,表示是某个Fruit子类(或者Fruit本身)的类型,这也就意味着X类型有多种可能性,而编译器无法判定是哪一个类型,所以通过这种方法声明的List无法添加元素,只允许取出元素,取出的元素全都会向上转型。


下边界限定通配符/超类型的通配符

用法:<? super Fruit>

即当前类型 X = ? super Fruit,类似X >= Fruit的感觉

这里的X类型,表示是某个Fruit父类(或者Fruit本身)的类型,虽然这里的X的类型也有多种可能性,但是编译器可以断定,只要加入的类型是Fruit子类或者Fruit本身,就一定可以向上转型。所以通过这种方法声明的List允许添加Fruit及其子类型的对象,加入的对象会自动向上转型成Fruit。

与上边界通配符的配合:

class Test {
    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));
    }
}

无边界通配符

用法:<?>

即当前类型X不限定范围,可能是任意的一个类型。所以自然也就无法向其添加任何元素了。用法类似于extends,不过get出来的是Object类型就是了。


PS

引子中的removeIf是一个默认方法,不得不赞一发,既扩展了接口方法,又不使得实现接口的类去添加新方法的覆盖,具体见参考资料。之后别人再问接口和抽象类的区别,就不能说普通类实现接口一定要实现所有方法了,2333。

参考资料

  1. Java 泛型总结(三):通配符的使用
  2. Java 8 默认方法(Default Methods)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值