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.
Note, with Scala version 2.13.x, this works out-of-the-box (no pun) without having to manually box the value.
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))
Since scala.Boolean
is a subclass of scala.AnyVal
but not scala.AnyRef
(translated to java.lang.Object
), a Boolean
cannot be passed to a method expecting Object
(s).
You can use the companion object scala.Boolean
to "box" (in Java's sense, of course) a boolean
into java.lang.Boolean
:
JavaClass.varargsMethod(Boolean.box(true))
The other AnyVal
classes have corresponding box
methods (e.g. Int.box
). There are also unbox
methods to do the opposite.
A more complicated use case:
JavaClass.varargsMethod(Seq(1, 2, 3, 4).map(Int.box): _*) // passes 1, 2, 3, 4
I don't know when these were added to the standard library, but with these you don't have to use the implementation classes of scala.runtime.*
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With