Brennschluss

a blog by Boris Terzic

« Back to blog

Pitfalls for Java programmers new to Scala: arrays and Scala to Java interoperability

Arrays in Java are special, not in a good way, but in a nasty exceptional, non-standard way. Being the only datatype to be parametrized (or "generic") since before Generics were introduced in Java they also have the property of being covariant: you can use an Array of Strings when one of Objects is required for example, since String is a subtype of Object Java considers the Array of String to be a subtype of Array of Object.

In Scala however, generics are quite clean and arrays are not so special and therefore not covariant by definition. This is fine and both worlds can coexist in peace and tranquility.

Until you start calling Java code from Scala.

The example that bit me was a piece of trivial Swing code where I wanted to instantiate a JComboBox with an array of Strings:

val comboBox = new JComboBox(Array("foo", "bar"))

Boom went the compiler: "error: overloaded method constructor JComboBox with alternatives (java.util.Vector[_])javax.swing.JComboBox <and> (Array[java.lang.Object])javax.swing.JComboBox <and> (javax.swing.ComboBoxModel)javax.swing.JComboBox cannot be applied to (Array[java.lang.String])"

Turns out that the JComboBox constructor takes an array of Objects (in order to be generic and allow any kind of object to be displayed in a combo box). The Scala compiler however does not "do what I want" and complains that it can't find a suitable constructor.

The fix is a simple as it is absolutely horrifyingly impossible to Google for, simply provide a generic type for your array that fits the Java API:

val comboBox = new JComboBox(Array[AnyRef]("foo", "bar"))

Note the "AnyRef". Easy peasy, if you know what's up. Thanks to Vassil Dichev for helping out a noob.