Scala 从泛型类型参数获取类型参数并在递归函数调用中使用
这段代码应该将JSON数组或JSON对象反序列化为其各自的scala类。我遇到的问题是这条线Scala 从泛型类型参数获取类型参数并在递归函数调用中使用,scala,generics,recursion,reflection,types,Scala,Generics,Recursion,Reflection,Types,这段代码应该将JSON数组或JSON对象反序列化为其各自的scala类。我遇到的问题是这条线 case x if x <:< typeOf[Array[_]] => deserialize[TypeTag[_]](s.getJSONArray(i))' 所以,虽然我不太明白它为什么会起作用,但我还是能够根据一系列其他的stackoverflow问题,共同制定出一个可行的解决方案 def deserialize[X](s: JSONObject)(implicit tTag:
case x if x <:< typeOf[Array[_]] => deserialize[TypeTag[_]](s.getJSONArray(i))'
所以,虽然我不太明白它为什么会起作用,但我还是能够根据一系列其他的stackoverflow问题,共同制定出一个可行的解决方案
def deserialize[X](s: JSONObject)(implicit tTag: TypeTag[X]): 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
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(s.getJSONArray(name))(getSubInfo(0)(typeToTypeTag(t, m)))
}
case t => deserialize(s.getJSONObject(name))(typeToTypeTag(t, m))
}
}
constructorMethod(args:_*).asInstanceOf[X]
}
def deserialize[X](s: JSONArray)(implicit tTag: TypeTag[X]): Array[X] = {
val mirror = runtimeMirror(getClass.getClassLoader)
implicit val xClassTag = ClassTag[X](mirror.runtimeClass(tTag.tpe))
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(s.getJSONArray(i))(getSubInfo[X](0))
}
case x => {
deserialize[X](s.getJSONObject(i))
}
}).asInstanceOf[X]
}
arr
}
def typeToTypeTag[T](tpe: Type, mirror: reflect.api.Mirror[reflect.runtime.universe.type]): TypeTag[T] = {
TypeTag(mirror, new reflect.api.TypeCreator {
def apply[U <: reflect.api.Universe with Singleton](m: reflect.api.Mirror[U]) = {
assert(m eq mirror, s"TypeTag[$tpe] defined in $mirror cannot be migrated to $m.")
tpe.asInstanceOf[U#Type]
}
})
}
def getSubInfo[X](i: Int)(implicit tTag: TypeTag[X]): TypeTag[_] = {
typeToTypeTag(tTag.tpe.asInstanceOf[TypeRefApi].args(i), tTag.mirror)
}
def反序列化[X](s:JSONObject)(隐式tTag:TypeTag[X]):X={
val m=ru.runtimeMirror(getClass.getClassLoader)
val classType=ru.typeOf[X].typeSymbol.asClass
val cm=m.reflectClass(类类型)
val constructor=typeTag.tpe.decl(ru.termNames.constructor).asMethod
val constructorMethod=cm.reflectConstructor(构造函数)
val params=constructor.asMethod.paramLists.head
val args=新数组[任何](参数长度)
for(i s.getString(名称)
如果t=:=typeOf[Int]=>s.getInt(name),则为案例t
如果t=:=typeOf[Double]=>s.getDouble(name),则为案例t
如果t=:=typeOf[Boolean]=>s.getBoolean(名称),则为案例t
如果t=:=typeOf[Long]=>s.getLong(name),则为案例t
案例t如果t{
反序列化(s.getJSONArray(name))(getSubInfo(0)(typeToTypeTag(t,m)))
}
案例t=>反序列化(s.getJSONObject(name))(typeToTypeTag(t,m))
}
}
构造函数方法(args:*).asInstanceOf[X]
}
def反序列化[X](s:JSONArray)(隐式tTag:TypeTag[X]):数组[X]={
val mirror=runtimeMirror(getClass.getClassLoader)
隐式val xClassTag=ClassTag[X](mirror.runtimeClass(tTag.tpe))
val arr=新数组[X](s.length())
for(i s.getString(i)
如果x=:=typeOf[Int]=>s.getInt(i),则为案例x
如果x=:=typeOf[Double]=>s.getInt(i),则为案例x
如果x=:=typeOf[Boolean]=>s.getInt(i),则为案例x
如果x=:=typeOf[Long]=>s.getInt(i),则为案例x
案例x如果x{
反序列化(s.getJSONArray(i))(getSubInfo[X](0))
}
案例x=>{
反序列化[X](s.getJSONObject(i))
}
}).ASINSTANCOF[X]
}
啊
}
def typeToTypeTag[T](tpe:Type,mirror:reflect.api.mirror[reflect.runtime.universe.Type]):TypeTag[T]={
TypeTag(镜像,新reflect.api.TypeCreator{
def apply[U@Markuse1189感谢您的编辑。我花了很长时间试图找出为什么反勾格式对我不起作用。
def deserialize[X](s: JSONObject)(implicit tTag: TypeTag[X]): 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
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(s.getJSONArray(name))(getSubInfo(0)(typeToTypeTag(t, m)))
}
case t => deserialize(s.getJSONObject(name))(typeToTypeTag(t, m))
}
}
constructorMethod(args:_*).asInstanceOf[X]
}
def deserialize[X](s: JSONArray)(implicit tTag: TypeTag[X]): Array[X] = {
val mirror = runtimeMirror(getClass.getClassLoader)
implicit val xClassTag = ClassTag[X](mirror.runtimeClass(tTag.tpe))
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(s.getJSONArray(i))(getSubInfo[X](0))
}
case x => {
deserialize[X](s.getJSONObject(i))
}
}).asInstanceOf[X]
}
arr
}
def typeToTypeTag[T](tpe: Type, mirror: reflect.api.Mirror[reflect.runtime.universe.type]): TypeTag[T] = {
TypeTag(mirror, new reflect.api.TypeCreator {
def apply[U <: reflect.api.Universe with Singleton](m: reflect.api.Mirror[U]) = {
assert(m eq mirror, s"TypeTag[$tpe] defined in $mirror cannot be migrated to $m.")
tpe.asInstanceOf[U#Type]
}
})
}
def getSubInfo[X](i: Int)(implicit tTag: TypeTag[X]): TypeTag[_] = {
typeToTypeTag(tTag.tpe.asInstanceOf[TypeRefApi].args(i), tTag.mirror)
}