基本上我想将非类型化的JSON读入由字符串指定的类型。伪代码。
def getObject(json: Json, typeString: String): typeOf(typeString) = extract[typeOf(typeString)](json)
typeOf
只是一些从字符串中提供类型的随机事物。
答案 0 :(得分:0)
我会说没有运行时反射是不可能的。使用运行时反射,我会尝试以下方法:
Class[_]
获取ClassLoader
的名称 - 仅当您在String
中指定了全名(包含所有内容)new ObjectMapper().readValue(json, obtainedClass)
,Any
- 理论上你可以在这里使用path-dependent types,但我个人认为收效甚微。然而:
嗯,我想你也可以将签名改为:
def getObject[T: ClassTag](json: Json): T
或
def getObject[T](json: Json, clazz: Class[T]): T
并确保该函数返回您想要的内容。通过名称获取类[_]并传递它会使我们减少原始解决方案。
编辑:
显示如何从鉴别器(伪代码)中提取类型的示例:
// store discriminator in DB
// use it to deserialize and dispatch with predefined function
def deserializeAndHandle(discriminator: String, json: String): Unit = discriminator match {
case "my.package.A" => decode[my.package.A](json).map(handlerForA)
case "my.package.B" => decode[my.package.B](json).map(handlerForB)
case "my.package.C" => decode[my.package.C](json).map(handlerForC)
case _ =>
}
deserializeAndHandle(discriminator, json)
// store discriminator in DB
// use it to deserialize to Object which can be pattern-matched later
def deserializeToObject(discriminator: String, json: String): Option[Any] = discriminator match {
case "my.package.A" => decode[my.package.A](json).toOption
case "my.package.B" => decode[my.package.B](json).toOption
case "my.package.C" => decode[my.package.C](json).toOption
case _ => None
}
deserializeToObject(discriminator, json) map {
case a : A => ...
case b : B => ...
case c : C => ...
} getOrElse ???
// wrap unrelated types with sealed trait to make it sum type
// use sum type support of Circe
sealed trait Envelope
final case class EnvelopeA(a: A) extends Envelope
final case class EnvelopeB(b: B) extends Envelope
final case class EnvelopeA(c: C) extends Envelope
def deserializeEnveloped(json): Option[Envelope] = decode[Envelope](json).toOption
deserializeEnveloped(json) map {
case EnvelopeA(a) => ...
case EnvelopeB(b) => ...
case EnvelopeC(c) => ...
} getOrElse ???