1. 有界泛型
1.1 有界泛型的定义
当我们需要一个工具类只用于做数值计算,或者只用于做集合的遍历,方法只希望接收Number或者Collection,不希望接受其他类型,否则就得写一大堆instanceof的if判断。
为了解决这个问题,我们需要定义泛型的上边界,即方法所能接收的层级最高的类型。
在Java中,用extends关键字可以实现有界泛型的定义。格式为:<T extends UpperBoundClass>,其中UpperBoundClass为上边界类型。代码实例如下所示:
代码清单1
在使用代码清单1的工具方法的时,可以这么使用:
代码清单2
可见,只要定义了边界,泛型方法就只会接收符合条件的类型。而当传入不属于边界类型的子类时,将会出现编译时的参数类型错误。
1.2 对边界类型的访问
除了可以限制类型之外,有界范型的定义还允许直接访问边界类型,比如:
代码清单3
在代码清单3中,虽然方法参数collection的类型还未确定,依然可以访问边界类型的公有方法。
1.3 多重边界类型
Java支持范型的多重边界的定义,但有一定的限制:
- 支持多接口类型边界。
- 支持有且仅有一个类边界及其他接口边界。
- 不支持多个类边界。
原因很简单,Java不支持类的多继承关系,所以一个类不可能有多个无关系的父类。
而接口可以多继承接口,所以支持多个接口类型边界。代码示例如下所示:
代码清单4
多重边界的范型,编译器类型擦出过后,总是保留最左侧的边界类型作为实际类型,在代码清单4中,computeCloneableNumber和visitCAndSObject在字节码中的方法参数分别为Number和Serializable:
附件
本博文所展示的源代码由此获得。
参考文献
[1] Josh Juneau.泛型:工作原理及其重要性[EB/OL].https://www.oracle.com/technetwork/cn/articles/java/juneau-generics-2255374-zhs.html,2019-07-02.
[2] The Java™ Tutorials - Generics[EB/OL].https://docs.oracle.com/javase/tutorial/java/generics/index.html,2019-07-02.
[3] The Java® Virtual Machine Specification[EB/OL].https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-4.html#jvms-4.3,2019-07-04.