Search code examples
javascalareflectionscala-reflect

How to type cast Any dynamically in scala?


I want to convert "Any" object into an object of runtime type. Based on the class name (string) at the runtime, how do I convert an ANY object to actual object?

I tried using converting class name into class object using Class.forName

val clazz = Class.forName("my.package.Animal")
val any: Any = Animal(1, "simba")
any.asInstanceOf[clazz] // Compilation Error // Looking for a solution

Solution

  • Try to use

    • compiler toolbox

      package my.package
      
      import scala.tools.reflect.ToolBox
      import scala.reflect.runtime.universe._
      
      case class Animal(id: Int, name: String)
      
      object App {    
        val any: Any = Animal(1, "simba")
        val className = "my.package.Animal"
      
        val mirror = runtimeMirror(getClass.getClassLoader)
        val tb = mirror.mkToolBox()
        tb.eval(tb.parse(
          s"""
            import my.package.App._
            val animal = any.asInstanceOf[$className]
            println(animal.id)
            println(animal.name)
          """))
      }
      

    libraryDependencies += scalaOrganization.value % "scala-reflect" % scalaVersion.value

    libraryDependencies += scalaOrganization.value % "scala-compiler" % scalaVersion.value

    • or Scala reflection

      import scala.reflect.runtime.universe._
      
      val mirror = runtimeMirror(getClass.getClassLoader)
      val classSymbol = mirror.staticClass(className)
      val typ = classSymbol.toType
      val idMethodSymbol = typ.decl(TermName("id")).asMethod
      val nameMethodSymbol = typ.decl(TermName("name")).asMethod
      val instanceMirror = mirror.reflect(any)
      val idMethodMirror = instanceMirror.reflectMethod(idMethodSymbol)
      val nameMethodMirror = instanceMirror.reflectMethod(nameMethodSymbol)
      println(idMethodMirror())
      println(nameMethodMirror())
      

    libraryDependencies += scalaOrganization.value % "scala-reflect" % scalaVersion.value

    • or Java reflection

      val clazz = Class.forName(className)
      val idMethod = clazz.getMethod("id")
      val nameMethod = clazz.getMethod("name")
      println(idMethod.invoke(any))
      println(nameMethod.invoke(any))