mardi 1 août 2017

Scala, how to create a generic object of a specific type, the class of which is only available at runtime as a string

given a string (say "345435.454") and another string (say "java.lang.Double") at runtime , how can I create a object of class/Type java.lang.Double with value given in first argument.

Using the second argument I can get the class and the type but I'm unable to get the TypeTag with generic Type "T" as java.lang.Double

scala>def getType[T](clazz: Class[T])(implicit runtimeMirror: ru.Mirror) =

 | runtimeMirror.classSymbol(clazz).toType

getType: [T](clazz: Class[T])(implicit runtimeMirror: reflect.runtime.universe.Mirror)reflect.runtime.universe.Type

scala> def cast[A](a:Any,tt: TypeTag[A]):A = a.asInstanceOf[A]
cast: [A](a: Any, tt: reflect.runtime.universe.TypeTag[A])A

-- from type to typetag

scala>def backward[T](tpe: Type): TypeTag[T] =
 TypeTag(mirror, new api.TypeCreator {
  def apply[U <: api.Universe with Singleton](m: api.Mirror[U]) =
   if (m eq mirror) tpe.asInstanceOf[U # Type]
   else throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.")
})
scala>def sToI(s:String) = Integer.valueOf(s)
scala>def parseDouble(s: String) = s.toDouble
scala>val conversionMap  = Map("java.lang.Integer" -> sToI , "java.lang.Double" -> parseDouble _ )


 // I have to provide typetag for java.lang.Double and hardcode it to get Double object
scala> cast(conversionMap("java.lang.Double")("345435.454"),typeTag[java.lang.Double])
res185: Double = 345435.454

// If try to get the typetag by using type from className , it doesn't work because I get typeTag[Nothing] => TypeTag[java.lang.Double]. backward is the function to get typetag from type
scala>backward(getType(Class.forName("java.lang.Double")))
res186: reflect.runtime.universe.TypeTag[Nothing] = TypeTag[Double]

Is there any way to get the reflect.runtime.universe.TypeTag[Double] = TypeTag[Double], with out providing the generic Type ?





Aucun commentaire:

Enregistrer un commentaire