Java泛型中的通配符
2017-03-20 20:47
330 查看
最近想学学集合框架的源代码,结果画风是这样的:
一下就暴露了泛型没好好学的锅= =,今天总结一下。
下文统一使用这两个类进行说明。
即当前类型
这个X类型,表示是某个Fruit子类(或者Fruit本身)的类型,这也就意味着X类型有多种可能性,而编译器无法判定是哪一个类型,所以通过这种方法声明的List无法添加元素,只允许取出元素,取出的元素全都会向上转型。
即当前类型
这里的X类型,表示是某个Fruit父类(或者Fruit本身)的类型,虽然这里的X的类型也有多种可能性,但是编译器可以断定,只要加入的类型是Fruit子类或者Fruit本身,就一定可以向上转型。所以通过这种方法声明的List允许添加Fruit及其子类型的对象,加入的对象会自动向上转型成Fruit。
与上边界通配符的配合:
即当前类型X不限定范围,可能是任意的一个类型。所以自然也就无法向其添加任何元素了。用法类似于
Java 8 默认方法(Default Methods)
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。
参考资料
Java 泛型总结(三):通配符的使用Java 8 默认方法(Default Methods)
相关文章推荐
- java泛型(三)、通配符的使用
- Java泛型解析(02):通配符限定
- java泛型(三)、通配符的使用
- java泛型学习,泛型通配符的理解
- java泛型中的通配符
- JAVA泛型和通配符
- java入门教程-5.7java泛型通配符和类型参数的范围
- Java泛型和通配符那点事
- 浅谈Java泛型通配符解决了泛型的许多诟病(如不能重载)
- java泛型通配符
- java泛型(三)、通配符的使用
- Java泛型中通配符的几点理解
- Java泛型-- 通配符
- Java泛型--通配符
- Java泛型和通配符那点事
- 详解Java泛型(四)之通配符类型
- Java泛型通配符T E K V 的区别,以及 class<T> 与 class<?>的区别
- Java泛型通配符extends与super
- Java泛型中通配符的几点理解
- java泛型通配符