Universal/generic boxing from Any to AnyRef
boxing, scala
Solution
Just cast to `AnyRef` with `asInstanceOf` and Scala will turn it into an `AnyRef`:
scala> val x = 13
x: Int = 13
scala> val xBoxed = x.asInstanceOf[AnyRef]
xBoxed: AnyRef = 13
scala> xBoxed.getClass()
res0: Class[_ <: AnyRef] = class java.lang.Integer
For value classes, this will box it in an instance of the value class, instead of the Java class. You could use a generic trait to be able to get the Java boxed versions from your value classes, without using reflection. For example:
trait ValueClass[T] extends Any {
def value: T
def javaBoxed: AnyRef = value.asInstanceOf[AnyRef]
}
case class MyInt(value: Int) extends AnyVal with ValueClass[Int]
case class MyReal(asDouble: Double) extends AnyVal with ValueClass[Double] {
def value = asDouble
}
However, this requires you mix your trait into all your value classes. For value classes that extend `Product`, like all case classes do, there's a quicker way using `productElement`:
def javaBox(x: Product): AnyRef = {
if (x.productArity == 1) x.productElement(0).asInstanceOf[AnyRef]
else x.asInstanceOf[AnyRef] // or throw an exception if you prefer
}
Unfortunately, it looks to me like both methods (mix-in trait and `Product`) cause Scala to do its boxing, meaning when called on an unboxed value, the value goes from unboxed → Scala boxed → unboxed → Java boxed, instead of straight to the Java boxed value.
Problem
Is it possible to force runtime boxing in scala dynamically? I would like a function: ``` def box(value :Any) :AnyRef ``` or ``` def box[T](value :T) :AnyRef ``` I have a generic class which may be parameterized with AnyVals but need to pass them to legacy java methods accepting collections of objects. Of course, I could implement it myself with pattern matching, but it's a bit annoying to have to do it time and time again, and it wouldn't work for user value classes. Edit The answer turned out as simple as surprising. Now, can I do it through reflection? Assume ``` class Box[T :TypeTag](private var value :T) { def get :T = value def set(o :Any) { ... } } ``` I would like to do a safe set, checking in the runtime if o is a subclass of T like this: ``` runtimeMirror(getClass.getClassLoader).classSymbol(o.getClass).toType <:< typeOf[T] ``` Unfortunately, typeOf[T] for Box[Long] will be a primitive, and the following check will fail on java.lang.Long, which is the runtime type of elements of Seq[Long] for example. Bottom line, when using generics with AnyVals, the compiler sometimes boxes them making runtime class checks unpredictible.