0

Assume there is a class X. At some point in my code, I get an o of type Object and I want to explicitly cast it to X. Normally, I would do val x: X = o.asInstanceOf[X]. However, X is not in scope, all I have is X's instance of Class, like so:

  1. I pass classOf[X] to my function as an argument called classOfX.
  2. Within my function, I would like to do val x: X = o.asInstanceOf[classOfX].

Is there a way to do this in Scala?

typeduke
  • 6,494
  • 6
  • 25
  • 34
  • 1
    possible duplicate of http://stackoverflow.com/questions/40220804/scala-cast-to-a-variable-type – Nagarjuna Pamu Oct 25 '16 at 14:17
  • It's not a duplicate. The function in the post you linked is generic, mine is not. As described above, there is no generic type argument `X`, but an argument of type `Class` called `classOfX`. – typeduke Oct 25 '16 at 14:28

1 Answers1

2

Only kind of. java.lang.Class has a cast method that lets you cast a Class[A] to an A. You could write a method like this:

def cast[A](o: Any, clazz: Class[A]): A = clazz.cast(o)

scala> cast("abc", classOf[String])
res10: String = abc

This will "work" for most classes, but not for Scala boxed primitives:

scala> cast(1, classOf[Int])
java.lang.ClassCastException: Cannot cast java.lang.Integer to int

And of course, casting only works modulo type erasure, so this will not immediately throw an exception:

scala> val a = List("a").getClass
a: Class[_ <: List[String]] = class scala.collection.immutable.$colon$colon

scala> cast(List(1), a)
res16: List[String] = List(1)

On the upside, it will also work with classes obtained at run time using getClass, like above.

The downside is that you should be avoiding casting at all costs, because of how error prone it will make the code. It throws type safety out the window. Rarely should anyone find themselves in a situation where they have an object where they don't know what it is, but can somehow tell the compiler what it is using classOf. It is likely that using some form of generics could eliminate a casting problem, but it is impossible to tell without more code.

Michael Zajac
  • 55,144
  • 7
  • 113
  • 138