Как динамически печатать Any в scala?

Я хочу преобразовать объект «Любой» в объект типа времени выполнения. Основываясь на имени класса (строке) во время выполнения, как мне преобразовать ЛЮБОЙ объект в фактический объект?

Я попытался использовать преобразование имени класса в объект класса, используя Class.forName

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

person sen    schedule 19.07.2019    source источник
comment
Могу я спросить, зачем вам это нужно? Я надеюсь, что есть лучшие альтернативы, чем приведение во время выполнения.   -  person Luis Miguel Mejía Suárez    schedule 20.07.2019
comment
спасибо @luis-miguel-mejía-suárez. Я сохранил объекты POJO в файле в виде байтовых массивов. И у меня есть сопоставление файлов с объектами. Когда я пытаюсь прочитать POJO из файла, мне нужно преобразовать их в правильные объекты.   -  person sen    schedule 20.07.2019
comment
Но зачем вам кастинг? Вы собираетесь вызывать методы для этих объектов? Как вы узнаете во время компиляции, какие методы доступны, если приведение является динамическим?   -  person Jasper-M    schedule 20.07.2019
comment
Я должен вызвать кучу функций установки, используя эти объекты. Думаю, я могу сопоставить шаблон и установить их   -  person sen    schedule 20.07.2019
comment
@sen Я знаю, что могут быть причины, которые не позволят тебе. Но я бы посоветовал вам изменить эти POJOS на Case Classes и использовать сериализатор, десериализатор, способный возвращать правильные типы, такие как Circe подойдет для JSON. - Теперь, если предположить, что вы не можете изменить код, можете ли вы поделиться реальным вариантом использования вашего кода? Например, как вы их читаете, как вы называете сеттеры и как бы вы хотели их разыгрывать.   -  person Luis Miguel Mejía Suárez    schedule 20.07.2019


Ответы (1)


Попробуй использовать

  • набор инструментов компилятора

    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))
    
person Dmytro Mitin    schedule 20.07.2019