本篇文章以个人经历为引子进行闲谈,并不涉及什么原理
一、何为联合类型
当我学习Kotlin时,见到了一种奇怪的范型写法
fun <T, R> callMax(a: T, b: T): R where T: Comparable<T>, T:() -> R, R: Number |
在Java里是这样的:
public static<T extends Comparable<T> & Supplier<T>, R extends Number> R callMax(T a, T b){} |
这引起了我强烈的好奇,这个&
是什么?
不难看出这里是“与”的关系,表示范型T
只能是实现了Comparable<T>
和Supplier<T>
两个接口的对象
具体来说就是联合类型,即把多个类型的特征结合起来形成的一种不真实存在的类型
部分人将其称为交集类型(Intersection type)
联合类型A & B
可看作一个类型U
,U
类型具有A
和B
类型的共同的特征,相当于U
继承自A
和B
二、如何在程序中使用
一句话总结:只能用于形参,不能用于实参,只是描述作用,不能当成正常的对象来使用
&
符号可以一直连接,但连接时必须把类放在接口前
因为Java没有函数类型,所以只能借助接口或者类来间接实现这个联合的功能
比如下面这个例子:
class MyA { |
最后的输出结果为:
t1 |
从上面这个例子可以看出来联合类型在Java联合类型的范型中的作用只能是描述,而非直接使用,我觉得原因在于Java会范型擦除,范型的类型无法保留下来,所以产生了这样奇奇怪怪的写法
我还在别人的文章中看到了这种使用方式
对lambda表达式进行强制类型转换:
public class Test { |
这也是一种很怪但又不是那么怪的写法,对于不知道这种形式的人来说根本看不大懂
不过根据前面学到的东西,这里联合类型其实也是起描述作用,而不能写在lambda表达式的括号(当作实参)里
目前了解的就这些了,范型擦除(伪范型)真是一个很神奇的东西呢~