泛型类是以类型作为参数,Scala类型参数放在方括号[]中,Java放在<>中
变型 Variance
Scala与Java一样,普通泛型类型都是不变的(invariant)
Scala支持对泛型类的类型参数添加变化型注释,使得他们是协变的(covariant),逆变的(contravariant)
- 协变Covariance:
A是B的子类,List[A]是List[B]的子类 - 逆变Contravariance:对于类
class C[-A],A是B的子类,C[B]是C[A]的子类 - 不变Invariance:
C[B]和C[A]没有任何关系
class C[+A] // A covariant class
class C[-A] // A contravariant class
class C[A] // An invariant class
对trait Function1[-T, +R]的理解
Scala标准库中Function1代表具有一个参数的函数,参数类型为T,第二个参数类型R 表示返回类型。
Function1 对它的参数类型来说是逆变,对返回类型来说是协变的(实际上所有函数都是这样的),函数字面量 A => B 表示为 Function1[A, B]
举例:
Animal => Mouse是Cat => SmallAnimal的子类型
abstract class Animal {
def name: String
}
case class Cat(name: String) extends Animal
case class Dog(name: String) extends Animal
abstract class SmallAnimal extends Animal
case class Mouse(name: String) extends SmallAnimal
Java数组具有协变性,泛型具有不变型(标准库中List<Object>和List<String>无关)
//Java代码,可以编译通过,运行抛出异常 java.lang.ArrayStoreException
Integer[] integer = new Integer[3];
Object[] objectsArray = integer;
objectsArray[0] = "dfg";
System.out.println(objectsArray[0]);
Scala数组类型是不变的,为了与Java数组的兼容,可以进行类型转换,转化为参数类型的任何父类型
scala> val a1 = Array("abc")
a1: Array[String] = Array(abc)
scala> val a2: Array[Object] = a1.asInstanceOf[Array[Object]] //不能直接复制,类型不同
a2: Array[Object] = Array(abc)
类型边界
不允许使用+号注解的类型参数作为方法的参数类型,此外由于可变字段var会自动产生setter方法,所以可变字段的类型也不能是协变类型,可以通过函数边界解决这个问题
//错误的代码
class Cell[+T](init: T) {
private[this] var current = init
def get = current
def set(x: T) = { current = x } //编译错误 covariant type T occurs in contravariant position in type T of value x
}
[B <: A] 上界upper bound:表示类型参数B对应类型为A的子类,类似于Java的<? extends A>
[B >: A] 下界lower bound:表示类型参数或抽象类型B对应类型为A的超类型,通常应用于A为协变类型,设定下界,B作为方法的类型参数
Java可以通过通配符实现变性
上界限定<? extends A>,实现了协变性,作为返回类型,或者类型参数
下界限定<? super A>,实现逆变性,作为输入类型
| 术语 | Scala | Java |
|---|---|---|
| Parametrized type | List[String] | List<String> |
| Actual type parameter | String | String |
| Generic type | List<A> | List<E> |
| Formal type parameter | A | E |
| Unbounded wildcard type | List[_] | List<?> |
| Raw type | List | List |
| Type parameter with lower bound | [A >: Number] | <E super Number> |
| Type parameter with upper bound | [A <: Number] | <E extends Number> |
| Wildcard type with lower bound | [_ >: Number] | <? super Number> |
| Wildcard type with upper bound | [_ <: Number] | <? extends Number> |
| Recursive type bound | [A <: Ordered[A]] | <T extends Comparable<T>> |
| Type constructor | List, constructs List[Int] etc | Same as in Scala |
| Variance annotation | + or - i.e. [+A] or [-A] | not supported |
| Covariance annotation | + i.e. [+A] | not supported |
| Contravariance annotation | - i.e. [-A] | not supported |






网友评论