A Java language quirk

The boys at Sun made really an amazing thing when designing Java. I mean, everyone is cursing it now, predicting Java is dead because of its verbosity and such but could those persons have done better?  I doubt it. Just consider Java 's penetration in the enterprise…​ Verbosity enforces readibility, a nice feature in the enterprise where people move from position to position, in and out.

However, I have stumbled upon a troubling quirk. Most Java’s nuts and bolts are enforced at compile time, and erased at runtime. If nothing wrong gets compiled, there’s no reason to check at runtime. The glitch I found compiles fine but throws an exception at runtime.

Consider the following piece of code:

Object[] objects= new String[1];
objects[0] = new Integer(5);

It compiles juts fine but if you execute it, you will be faced with an strange java.lang.ArrayStoreException…​ Which statement is wrong? Obviously, the first one. How can an array of strings can be considered an array of objects?

Now, I’m not too fond of generics and the convoluted way they are implemented in Java 5 but this particular quirk is not possible with them. None of the two following snippets will compile:

// Type mismatch: cannot convert from ArrayList<String> to List<Object>
List<Object> list = new ArrayList<String>();

List<? extends Object> list = new ArrayList<String>();
// The method add(capture#1-of ? extends Object) in the type
//  List<capture#1-of ? extends Object> is not applicable for the arguments (Integer)
list.add(new Integer(3));

For those interested in theory, this behaviour where an array of String can be seen as an array of Object is called covariance. Funny to say it, but Java 5 generics are actually an improvement over array whereas covariance is concerned!

Note that Scala makes arrays nonvariant at compile-time and thus correctly handles the problem:

// type mismatch;  found   : Array[String]  required: Array[java.lang.Object]
var array:Array[Object] = new Array[String](0)
Nicolas Fränkel

Nicolas Fränkel

Nicolas Fränkel is a Developer Advocate with 15+ years experience consulting for many different customers, in a wide range of contexts (such as telecoms, banking, insurances, large retail and public sector). Usually working on Java/Java EE and Spring technologies, but with focused interests like Rich Internet Applications, Testing, CI/CD and DevOps. Currently working for Hazelcast. Also double as a teacher in universities and higher education schools, a trainer and triples as a book author.

Read More