Recent changes

Arrays references are not Covariant

What’s wrong with the following code?

String[] s = { "a", "b", "c" };
Object[] o = s;

The second line is not type-safe. Why? Because arrays aren’t like most other expressions. You don’t just read from them; you also store to them (something you can’t do with other expressions). The following code demonstrates the type unsafe-ness.

1 o[1] = new Object(); // We just put an Object in the array...
2 String s1 = s[1];    // ...but this guy still thinks they're all Strings!
3 print("s[1].length = " + s1.length());

Line 3 is trying to call the “length()” method on an “Object”. The compiler has no clue that this will fail.

Java and C# will give you a runtime exception at line 1 because the VM performs a dynamic type-check when you store a value to an array. Not only do you lose static type safety, but you also take a performance hit. Stupid, huh?

Anyway, this problem was one they could have solved by requiring variance annotations. For arrays, this boils down to annotations that say “I promise never to write to this array” or “I promise never to read from this array.” Let’s say that the ‘+’ symbol refers to the first promise (covariance) and the ‘-’ symbol refers to the second (contravariance). The original example becomes:

1 String[] s = { "a", "b", "c" }
2 Object+[] o = s;
3 o[1] = new Object();
4 print(o[1].toString());

Now, you’ll get a compile error saying something like:

Line 3: You promised not to write to this array.

Line 4 still works because you’re allowed to read from it.

(The “Type+” and “Type-” syntax was used in some of the early proposals for adding generics to Java. Sun decided to go with “<? extends Type>” and “<? super Type>” instead.)

So what about contravariance. When would you want to be able to store to an array but never read from it?

void ComponentArrayCopy(Component+[] source, Component-[] dest)
{
   // copy the stuff
}

Now you can safely copy Components from one array to another. Or you can copy elements from an array of SpecializedComponents to an array of Objects. (This example would be even more impressive with generic type parameters).

data/array_variance.txt Last modified: 01.10.2008 00:37
Driven by DokuWiki