'. '

Erasure

From APIDesign

(Difference between revisions)
Jump to: navigation, search
(New page: It is well known that while Covariance and Contravariance work OK from the source compatibility point of view in Java, but they are not very BackwardCompatible from the bin...)
Line 13: Line 13:
<source lang="java" snippet="variance.erasure.v2"/>
<source lang="java" snippet="variance.erasure.v2"/>
-
Obviously, this is source compatible as this is [[Contravariant]] extension of the range of values the method can absorb. Surprising (at least for those who remember that [[Contravariance]] is not binary compatible) is that this change is also binary compatible - e.g. it is fully [[BackwardCompatible]]! The is caused by the [[Erasure]] of generic type information. When compiled into binary form, the signature method is just {{JDK|java/util|Set}} (without any additional generic information), so the [[JVM]] sees no change between version 1.0 of the API and version 2.0. Both work on {{JDK|java/util|Set}}s.
+
Obviously, this is source compatible as this is [[Contravariance|contravariant]] extension of the range of values the method can absorb. Surprising (at least for those who remember that [[Contravariance]] is not binary compatible) is that this change is also binary compatible - e.g. it is fully [[BackwardCompatible]]! The is caused by the [[Erasure]] of generic type information. When compiled into binary form, the signature method is just {{JDK|java/util|Set}} (without any additional generic information), so the [[JVM]] sees no change between version 1.0 of the API and version 2.0. Both work on {{JDK|java/util|Set}}s.

Revision as of 05:43, 18 October 2011

It is well known that while Covariance and Contravariance work OK from the source compatibility point of view in Java, but they are not very BackwardCompatible from the binary point of view. As the binary compatibility is one of the most important ones for a compiled language like Java, one could think, that usage of Covariance or Contravariance is impossible. However it is not (at least not completely) - with the help of erasure of generic type information in Java one can use both-variances to own benefits.

Imagine there is a simple method that operates on set of integers:

Code from Erasure.java:
See the whole file.

public static boolean arePositive(Collection<? extends Integer> numbers) {
    for (Integer n : numbers) {
        if (n <= 0) {
            return false;
        }
    }
    return true;
}
 

Any user of such API can call this method with a set of Integers:

Code from ErasureTest.java:
See the whole file.

List<Integer> oneToTen = Arrays.asList(2, 4, 6, 8, 10);
boolean positive = arePositive(oneToTen);
System.err.println("positive = " + positive);
assert positive : "All the numbers are positive: " + oneToTen;
 

Later somebody decides that it would be nice to change method to accept not only integers, but all numbers and creates new version of the API with the same method, but accepting wider parameter types:

Code from Erasure.java:
See the whole file.

public static boolean arePositive(Collection<? extends Number> numbers) {
    for (Number n : numbers) {
        if (n.doubleValue() <= 0.0d) {
            return false;
        }
    }
    return true;
}
 

Obviously, this is source compatible as this is contravariant extension of the range of values the method can absorb. Surprising (at least for those who remember that Contravariance is not binary compatible) is that this change is also binary compatible - e.g. it is fully BackwardCompatible! The is caused by the Erasure of generic type information. When compiled into binary form, the signature method is just Set (without any additional generic information), so the JVM sees no change between version 1.0 of the API and version 2.0. Both work on Sets.

Personal tools
buy