johnsam johnsam - 2 months ago 23
Scala Question

Java Array vs Scala Array

Seems one difference between Java Array and Scala Array is Java Array is co variant. Scala Array is not. Both are mutable. In java, sort method can take different arrays, such as arrays of String or Int. This is often quoted as a good example of Liskov substitution principle. Seems a good design to me? In Scala we know Array is not co variant. Although Scala Array is designed later than Java. I can't see how Scala Array is better in the aspect of co-variance. It has generic maybe this is better than Java.

Answer

When you look further, you will find that the fathers of the Java language later decided to make Generics not covariant. And that is for good reasons.

Because a List<Apple> is not a List<Fruit>. Otherwise, you could do things like

List<Apple> apples = new ArrayList<>();
List<Fruit> fruits = apples;
fruits.add(new Banana());

but wouldnt you expect that

Apple badApple = apples.get(0);

is a safe call? If you allow for covariance here, it is not!

And surprise: that is the problem that Java arrays have!

Therefore it is really a problem that Java arrays are covariant! And it is better that Scala arrays actually allow you to exactly control their "variance". In Scala, you have full control over variance; whereas in Java, they are always covariant.

Having covariant arrays was seen as pragmatic way to allow for "generic" methods like sort(Object[] objects) long before anybody thought of having generics in Java. That is almost 20 years in the past. The "modern" way is, as you can see: doing things differently.

The "cost" of this decision is the fact that Java also knows ArrayStoreException. That would not be necessary, if Java arrays would not be covariant!