Covariance
From APIDesign
Everything one would ever like to know about Covariance and Contravariance is available at wikipedia. Here is just a small example to show how it does not work in Java.
Imagine simple program that computes maximum from two integers:
does not exists: variance.covariance.v1
due to a mistake the version 1.0 of the program does not return an Integer, but rather its super type Number. This is not a complete mistake, even plain Number can be useful, but its usage is a bit cumbersome. One needs to convert it to int first:
does not exists: variance.covariance.test
Now imagine that the author of the API decides to fix the design flaw and release version 2.0 of the API where the method will return an Integer:
does not exists: variance.covariance.v2
This is a fine change from the point of view of SourceCompatibility. Every (reasonable) code that compiled with version 1.0 will still compile (as Integer contains all the method one could call on Number). However this is heavily incompatible change from the point of BinaryCompatibility. Programs compiled against version 1.0 will not link against version 2.0. Unlike JavaC, the JVM seeks for the proper method using an exact match. Only method with one Number argument needs to be present and no tricks with polymorphism can help you cheat the JDK:
Mixing does not work: Compiling against version 1.0 and running against version 2.0 of the API fails: Exception in thread "main" java.lang.NoSuchMethodError: api.Covariance.max(II)Ljava/lang/Number; at test.CovarianceTest.main(Unknown Source)
As a result one cannot use Covariance or Contravariance in Java much. Unless one relies of on other side effects: There is a larger example demonstrating that Covariance may work in Java undercertain circumstances.