Contravariance

From APIDesign

(Difference between revisions)
Jump to: navigation, search
Line 7: Line 7:
<source lang="java" snippet="variance.contravariance.v2"/>
<source lang="java" snippet="variance.contravariance.v2"/>
-
Existing code would compile against the new library. However because the rules for looking up the right method are different between [[JavaC]] and [[JVM]] code like following will have problems:
+
Existing code would compile against the new library. However because the rules for looking up the right method are different between [[JavaC]] and [[JVM]], we'll have a problem. Code like this will compile fine, but...
<source lang="java" snippet="variance.contravariance.test"/>
<source lang="java" snippet="variance.contravariance.test"/>
-
If compiled against version 1.0 and executed against version 2.0, it will throw linkage errors:
+
...if compiled against version 1.0 and executed against version 2.0, it will throw linkage errors:
<source lang="bash">
<source lang="bash">

Revision as of 09:21, 13 December 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 (the argumentation is the same as in case of Covariance). First version would like to be fixed:

Code from Contravariance.java:
See the whole file.

public static boolean isPositive(Integer aNumber) {
    return aNumber > 0;
}
 

However when one tries to change the parameter type:

Code from Contravariance.java:
See the whole file.

public static boolean isPositive(Number aNumber) {
    return aNumber.doubleValue() > 0.0d;
}
 

Existing code would compile against the new library. However because the rules for looking up the right method are different between JavaC and JVM, we'll have a problem. Code like this will compile fine, but...

Code from ContravarianceTest.java:
See the whole file.

public static void main(String[] args) {
    boolean positive = Contravariance.isPositive(10);
    boolean negative = Contravariance.isPositive(-5);
    assert positive : "10 is positive";
    assert !negative : "-5 is negative";
}
 

...if compiled against version 1.0 and executed against version 2.0, it will throw linkage errors:

Mixing should not work: Compiling with version 1.0 and running against version 2.0 fails.
Exception in thread "main" java.lang.NoSuchMethodError: api.Contravariance.isPositive(Ljava/lang/Integer;)Z
	at test.ContravarianceTest.main(Unknown Source)
Java Result: 1

More info at Covariance. For possible trick around this behavior see Erasure.

Personal tools
buy