# A Complete Guide to Variance in Java and Scala

## Bounds to the rescue

`public void process(List<? extends Car> list) { ... }`
`public void process(List<? super Car> list) { ... }`
`List<? extends Integer> a = new ArrayList<Integer>();List<? super Integer> b = new ArrayList<Integer>();a.add(3);    // fails; let’s try with nulla.add(null); // worksb.add(3);    // no problem hereInteger ai = a.get(0); // no problem here eitherInteger bi = b.get(0); // fails; let’s try with ObjectObject o = b.get(0);   // works`
`                upper bound            lower bound       null ------------------- Car ------------------- Object`

`public class Foo<T> { ... }...Foo<? extends Integer> covariantFoo = new Foo<Integer>();Foo<? super Integer> contravariantFoo = new Foo<Integer>();`
`class CovariantFoo[+T] { ... }class ContravariantFoo[-T] { ... }...val covariantFoo = new CovariantFoo[Int]()val contravariantFoo = new ContravariantFoo[Int]()`
`Covariance                           if A is a subtype of B then:Java:  L<A> is a subtype of L<? extends B> (use-site)Scala: L[A] is a subtype of L[_ <: B]      (use-site)       L[A] is a subtype of L[+B]          (declaration-site)Contravarianceif A is a supertype of B then:Java:  L<A> is a subtype of L<? super B> (use-site)Scala: L[A] is a subtype of L[_ >: B]    (use-site)       L[A] is a subtype of L[-B]        (declaration-site)`

## Variance in function subtyping

`trait Function1[-S, +T] { def apply(x: S): T }`
`def getCarInfo: Car => AnyRef`
`1   /**2    * Remember! In Scala, every function that takes one argument 3    * is an instance of Function1 with signature:4    *5    * trait Function1[-T, +S] extends AnyRef6    */7   8   class Vehicle(val owner: String)9   class Car(owner: String) extends Vehicle(owner)10  11  object Printer {1213    val cars = List(new Car("john"), new Car("paul"))1415    def printCarInfo(getCarInfo: Car => AnyRef) {16      for (car <- cars) println(getCarInfo(car))17    }18  }19  20  object Customer extends App {2122   val getOwnerInfo: (Vehicle => String) = _.owner23   24   Printer.printCarInfo(getOwnerInfo)25  }`
`def printCarInfo(getCarInfo: Car => AnyRef)`
`val getOwnerInfo: (Vehicle => String) = _.owner`

Written by