In Java, a List<String>
is not a List<CharSequence>
even though a
String
is a CharSequence
.
void m1(java.util.List<CharSequence> s) {} void m2(java.util.List<String> s) { m1(s); } // bzzt!
Java's type parameters are always invariant, but would be nice if they were covariant[9].
Covariance doesn't mix well with side-effects[10]
But we aren't married to them anymore! We can have covariance, at a small cost — since we are still
dating them. We use +
to denote covariance[11]
scala> trait List[+A] { val head: A; val tail: List[A] } scala> val x = new List[String] { val head = "abc"; val tail = null } scala> val y: List[CharSequence] = x