New page: Everything one would ever like to know about Covariance and Contravariance is available at wikipedia. Here is just a ...
New page
Everything one would ever like to know about [[Covariance]] and [[Contravariance]] is available at [[wikipedia:Covariance_and_contravariance_(computer_science)|wikipedia]]. Here is just a small example how it does not work in [[Java]].
Imagine simple program that computes maximum from two integers:
<source lang="java" snippet="variance.covariance.v1"/>
due to mistake the version 1.0 of the program does not return an {{JDK|java/lang|Integer}}, but rather its super type {{JDK|java/lang|Number}}. Such return type can still be used to perform some useful operations, but it is cumbersome:
<source lang="java" snippet="variance.covariance.test"/>
Thus in version 2.0 the author of the [[API]] may decide to fix the type to {{JDK|java/lang|Integer}}:
<source lang="java" snippet="variance.covariance.v2"/>
This is a [[BackwardCompatible]] change from the source point of view. Every (reasonable) code that compiled with version 1.0 will still compile (as {{JDK|java/lang|Integer}} contains all the method one could call on {{JDK|java/lang|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:
<source lang="bash">
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)
</source>
As a result one can use [[Covariance]] or [[Contravariance]] in [[Java]] much. Unless one relies of [[Erasure]].