JaroslavTulach at 15:32, 14 July 2016 - 2016-07-14 15:32:14

←Older revision Revision as of 15:32, 14 July 2016
Line 22: Line 22:
As a result one cannot use [[Covariance]] or [[Contravariance]] in [[Java]] much. Unless one relies of on other side effects: There is a [[Erasure|larger example]] demonstrating that [[Covariance]] may work in [[Java]] undercertain circumstances.
As a result one cannot use [[Covariance]] or [[Contravariance]] in [[Java]] much. Unless one relies of on other side effects: There is a [[Erasure|larger example]] demonstrating that [[Covariance]] may work in [[Java]] undercertain circumstances.
 +
 +
 +
[[Category:APIDesignPatterns]]
 +
[[Category:APIDesignPatterns:Evolution]]

JaroslavTulach at 17:27, 19 October 2011 - 2011-10-19 17:27:38

←Older revision Revision as of 17:27, 19 October 2011
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 to show how it does not work in [[Java]].
Imagine simple program that computes maximum from two integers:
Imagine simple program that computes maximum from two integers:
Line 5: Line 5:
<source lang="java" snippet="variance.covariance.v1"/>
<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:
+
due to a 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}}. This is not a complete mistake, even plain {{JDK|java/lang|Number}} can be useful, but its usage is a bit cumbersome. One needs to convert it to '''int''' first:
<source lang="java" snippet="variance.covariance.test"/>
<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}}:
+
Now imagine that the author of the [[API]] decides to fix the design flaw and release version 2.0 of the [[API]] where the method will return an {{JDK|java/lang|Integer}}:
<source lang="java" snippet="variance.covariance.v2"/>
<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:
+
This is a fine change from the point of view of [[SourceCompatibility]]. Every ([[InstanceOf|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 [[BinaryCompatibility]]. Programs compiled against version 1.0 will not link against version 2.0. Unlike [[JavaC]], the [[JVM]] seeks for the proper method using an exact match. Only method with one {{JDK|java/lang|Number}} argument needs to be present and no tricks with polymorphism can help you cheat the [[JDK]]:
<source lang="bash">
<source lang="bash">
Line 21: Line 21:
</source>
</source>
-
As a result one can use [[Covariance]] or [[Contravariance]] in [[Java]] much. Unless one relies of [[Erasure]].
+
As a result one cannot use [[Covariance]] or [[Contravariance]] in [[Java]] much. Unless one relies of on other side effects: There is a [[Erasure|larger example]] demonstrating that [[Covariance]] may work in [[Java]] undercertain circumstances.

JaroslavTulach: New page: Everything one would ever like to know about Covariance and Contravariance is available at wikipedia. Here is just a ... - 2011-10-18 05:41:53

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]].