协变、逆变、非变
spark的源代码中大量使用到了协变、逆变、非变,学习该知识点对我们将来阅读spark源代码很有帮助。
来看一个类型转换的问题:
class Pair[T]
object Pair {
def main(args: Array[String]): Unit = {
val p1 = Pair("hello")
// 编译报错,无法将p1转换为p2
val p2:Pair[AnyRef] = p1
println(p2)
}
}
如何让带有泛型的类支持类型转换呢?
非变
语法格式
class Pair[T]{}
默认泛型类是非变的
类型B是A的子类型,Pair[A]和Pair[B]没有任何从属关系
Java是一样的
协变
语法格式
class Pair[+T]
类型B是A的子类型,Pair[B]可以认为是Pair[A]的子类型
参数化类型的方向和类型的方向是一致的
逆变
语法格式
class Pair[-T]
类型B是A的子类型,Pair[A]反过来可以认为是Pair[B]的子类型
参数化类型的方向和类型的方向是相反的
示例
示例说明
定义一个Super类、以及一个Sub类继承自Super类
使用协变、逆变、非变分别定义三个泛型类
分别创建泛型类来演示协变、逆变、非变
参考代码:
class Super
class Sub extends Super
class Temp1[T]
class Temp2[+T]
class Temp3[-T]
def main(args: Array[String]): Unit = {
val a:Temp1[Sub] = new Temp1[Sub]
// 编译报错
// 非变
//val b:Temp1[Super] = a
// 协变
val c: Temp2[Sub] = new Temp2[Sub]
val d: Temp2[Super] = c
// 逆变
val e: Temp3[Super] = new Temp3[Super]
val f: Temp3[Sub] = e
}