Contravariance
From APIDesign
(Difference between revisions)
(One intermediate revision not shown.) | |||
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]] | + | 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: | |
<source lang="bash"> | <source lang="bash"> | ||
Line 21: | Line 21: | ||
More info at [[Covariance]]. For possible trick around this behavior see [[Erasure]]. | More info at [[Covariance]]. For possible trick around this behavior see [[Erasure]]. | ||
+ | |||
+ | [[Category:APIDesignPatterns]] | ||
+ | [[Category:APIDesignPatterns:Evolution]] |
Current revision
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.