【发布时间】:2015-08-12 15:57:45
【问题描述】:
此代码应该将 JSON 数组或 JSON 对象反序列化到其各自的 scala 类中。我遇到的问题是这条线
case x if x <:< typeOf[Array[_]] => deserialize[TypeTag[_]](s.getJSONArray(i))'
我希望该函数检测 X 类型参数是否是某物的数组,并将该某物作为类型参数传递给递归函数调用。
所以如果我调用deserialize[Array[Int]](JSONArray),它应该返回一个Array[Array[Int]]。我需要以某种方式从Array[Int] 中提取Int 并将其传递给deserialize[???](JSONArray)。
def deserialize[X: TypeTag](s: JSONObject): X = {
val m = ru.runtimeMirror(getClass.getClassLoader)
val classType = ru.typeOf[X].typeSymbol.asClass
val cm = m.reflectClass(classType)
val constructor = typeTag.tpe.decl(ru.termNames.CONSTRUCTOR).asMethod
val constructorMethod = cm.reflectConstructor(constructor)
val params = constructor.asMethod.paramLists.head
val args = new Array[Any](params.length)
for(i <- params.indices) {
val name = params(i).name.decodedName.toString
println(params(i).typeSignature.toString)
args(i) = params(i).typeSignature match {
case t if t =:= typeOf[String] => s.getString(name)
case t if t =:= typeOf[Int] => s.getInt(name)
case t if t =:= typeOf[Double] => s.getDouble(name)
case t if t =:= typeOf[Boolean] => s.getBoolean(name)
case t if t =:= typeOf[Long] => s.getLong(name)
case t if t =:= typeOf[Array[_]] => deserialize[WeakTypeTag[_]](s.getJSONArray(name))
case t => deserialize[t.type](s.getJSONObject(name))
}
}
constructorMethod(args:_*).asInstanceOf[X]
}
def deserialize[X: ClassTag: TypeTag](s: JSONArray): Array[X] = {
val arr = new Array[X](s.length())
for(i <- 0 until s.length) {
arr(i) = (typeOf[X] match {
case x if x =:= typeOf[String] => s.getString(i)
case x if x =:= typeOf[Int] => s.getInt(i)
case x if x =:= typeOf[Double] => s.getInt(i)
case x if x =:= typeOf[Boolean] => s.getInt(i)
case x if x =:= typeOf[Long] => s.getInt(i)
case x if x <:< typeOf[Array[_]] => deserialize[TypeTag[_]](s.getJSONArray(i))
case x => deserialize[X](s.getJSONObject(i))
}).asInstanceOf[X]
}
arr
}
【问题讨论】:
-
@Markuse1189 感谢您的编辑。我花了很长时间试图弄清楚为什么反引号格式对我不起作用。
标签: scala generics recursion reflection types