Contravariance
From APIDesign
(Difference between revisions)
(New page: Everything one would ever like to know about Covariance and Contravariance is available at wikipedia. Here is just a ...) |
|||
(2 intermediate revisions not shown.) | |||
Line 1: | Line 1: | ||
- | 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]]. | + | 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]] (the argumentation is the same as in case of [[Covariance]]). First version would like to be fixed: |
- | [[ | + | <source lang="java" snippet="variance.contravariance.v1"/> |
+ | |||
+ | However when one tries to change the parameter type: | ||
+ | |||
+ | <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]], we'll have a problem. Code like this will compile fine, but... | ||
+ | |||
+ | <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"> | ||
+ | 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 | ||
+ | </source> | ||
+ | |||
+ | 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.