首页 > 解决方案 > 如何在scala中动态键入cast Any?

问题描述

我想将“任何”对象转换为运行时类型的对象。基于运行时的类名(字符串),如何将 ANY 对象转换为实际对象?

我尝试使用 Class.forName 将类名转换为类对象

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

标签: javascalareflectionscala-reflect

解决方案


尝试使用

  • 编译器工具箱

    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

  • 或 Scala 反射

    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

  • 或 Java 反射

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

推荐阅读