views:

183

answers:

1

I have the following code in Java:

public class JavaClass {

    public static void method( Object x ) {
    }

    public static void varargsMethod( Object... x ) {
    }

}

When I try and access it from Scala,

object FooUser {
  JavaClass.method(true)
  JavaClass.varargsMethod(true) // <-- compile error
}

I get the following compile error:

type mismatch; found : Boolean(true) required: java.lang.Object Note: primitive types are not implicitly converted to AnyRef. You can safely force boxing by casting x.asInstanceOf[AnyRef]

The error message is very helpful and shows how to fix the error, but I was wondering why the compiler is (apparently) happy to implicitly convert a scala.Boolean in one method call but not the other. Is this a bug or intentional?

Updated to add: I'm using Scala 2.8. If I make the varargsMethod signature

public static <T> void varargsMethod(T... xs) {

instead, then the error also goes away. I'm still puzzled as to why the compiler can't figure it out.

+4  A: 

Scala varargs and Java varargs are different. You need to do a conversion:

def g(x: Any*) = x.asInstanceOf[scala.runtime.BoxedObjectArray]
.unbox(x.getClass)
.asInstanceOf[Array[Object]]  
...
JavaClass.varargsMethod(g(true))

or (in 2.8.0+)

JavaClass.varargsMethod(java.util.Arrays.asList(true))
Vasil Remeniuk
The 2.8 "Arrays.asList(true)" version does not work, as it gives a single argument to "varargsMethod" of type "Arrays$ArrayList". However, finding a workaround is not really a problem -- the error message shows how to fix the error -- rather I wanted to know why the compiler wouldn't compile this call when it will for others in similar situations.
Matt R