samedi 24 mars 2018

Scala Reflection - Instantiate Class with argument type Map[], List[]

For the context, I am trying to build a method to inspect a given Type hierarchy, and construct the instance along with it's composite types using runtime reflection. The issue I have is when the class argument types is one of the composites - Map, Queue, List, etc. I get a type mismatch exception, which is expected, when we try to assign Any to one of those composite argument types.

I use reflection to extract the primary constructor's MethodMirror, and call the instantiation of the form:

constructorMethodMirror(args:_*)

For the primitives, auto-conversion seems to be doing it's job.

For reference here's the scala reflection documentation.. http://docs.scala-lang.org/overviews/reflection/overview.html#instantiating-a-type-at-runtime

My ADT sample that I'd like to initialize using reflection:

case class someADT(name:String, id:Int, customConfig:Map[String, Any]= Map())

object someADT{
    def apply(name:String, id:Int, ccfg:Map[String, Any]):someADT = 
        new someADT(name, id, ccfg)
}
val adt = someADT(name="myname", id=1, ccfg = Map("One" -> 1))

What's causing the dynamic invocation to fail is (use of var is to describe the issue. Below assignment of any works when you do .asInstanceOf[<expected type>]):

scala> var myMap:scala.collection.immutable.Map[String, Int] = scala.collection.immutable.Map()
        myMap: scala.collection.immutable.Map[String,Int] = Map()

        scala> val anyMap:Any = scala.collection.immutable.Map[String, Int]()
        anyMap: Any = Map()

        scala> myMap = anyMap
        <console>:25: error: type mismatch;
         found   : Any
         required: scala.collection.immutable.Map[String,Int]
               myMap = anyMap
                       ^





Aucun commentaire:

Enregistrer un commentaire