Covariance

From APIDesign

(Difference between revisions)
Jump to: navigation, search

JaroslavTulach (Talk | contribs)
(New page: Everything one would ever like to know about Covariance and Contravariance is available at wikipedia. Here is just a ...)
Next diff →

Revision as of 05:41, 18 October 2011

Everything one would ever like to know about Covariance and Contravariance is available at wikipedia. Here is just a small example how it does not work in Java.

Imagine simple program that computes maximum from two integers:

Code from Covariance.java:
See the whole file.

public static Number max(int n1, int n2) {
    return Math.max(n1, n2);
}
 

due to mistake the version 1.0 of the program does not return an Integer, but rather its super type Number. Such return type can still be used to perform some useful operations, but it is cumbersome:

Code from CovarianceTest.java:
See the whole file.

public static void main(String[] args) {
    Number n = Covariance.max(10, 20);
    System.err.println("value: " + n + " type: " + n.getClass());
    assert n.intValue() == 20 : "The max should be 20, but was: " + n;
}
 

Thus in version 2.0 the author of the API may decide to fix the type to Integer:

Code from Covariance.java:
See the whole file.

public static Integer max(int n1, int n2) {
    return Math.max(n1, n2);
}
 

This is a BackwardCompatible change from the source point of view. 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 binary compatibility. Programs compiled against version 1.0 will not link against version 2.0 as the JVM seeks method that takes exactly one Number argument and does not do any tricks with polymorphism at all:

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 can use Covariance or Contravariance in Java much. Unless one relies of Erasure.

Personal tools
buy