Re: how can i reflect the instantiated return type of a generic type's method?
LiangQing <[email protected]> Mon, 14 Mar 2016 11:28:02 +0800
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CAJ2h+mgRscuJBCrRPFP7MJr-d9R9Y8JUN+Cc2-O8uNSyYGNo+Q@mail.gmail.com> |
Thanks Daniel. It solves my problem. I'm sorry for submitting the question to the wrong mail list. On Sun, Mar 13, 2016 at 1:12 AM, Daniel Armak <[email protected]> wrote: > BTW Leon, please submit usage questions to the scala-user mailing list. > scala-language is for discussing the language itself. > > Daniel Armak > > On Sat, Mar 12, 2016 at 6:47 PM, Daniel Armak <[email protected]> wrote: > >> You need to use Symbol.typeSignatureIn(Type): >> >> scala> case class Person[T](name: T) >> defined class Person >> >> scala> val tpe = typeOf[Person[String]] >> tpe: reflect.runtime.universe.Type = Person[String] >> >> scala> val method = tpe.members.find(_.name.toString == "name").get.asMethod >> method: reflect.runtime.universe.MethodSymbol = value name >> >> scala> val methodType = method.typeSignatureIn(tpe) >> methodType: reflect.runtime.universe.Type = => String >> >> scala> methodType.resultType >> res24: reflect.runtime.universe.Type = String >> >> >> >> Daniel Armak >> >> On Mon, Mar 7, 2016 at 11:09 AM, Leon <[email protected]> wrote: >> >>> Hi, >>> >>> I have just write a method to reflect the methods of case class, but >>> meet some problem, the code is: >>> >>> >>> case class Name(first: String, last: String) >>> case class Person[T](name: T, age: Int) >>> case class America(val name: Name, val age: Int) >>> >>> val m = runtimeMirror(getClass.getClassLoader) >>> >>> def getFlattenFields(tag: Type, prefix: String = ""): Map[String, >>> Method] = { >>> val cls = m.runtimeClass(tag) >>> tag.members.filter(sym => >>> sym.isMethod && sym.asMethod.isGetter && >>> sym.asMethod.isPublic >>> ).flatMap { sym => >>> val methodSym = sym.asMethod >>> val returnType = methodSym.returnType >>> * // When reflect generic types, the returnType will be >>> something like 'T' but not the* >>> * // instantiated return type, how can i get the real return >>> type instead of the generic* >>> * // type ?* >>> Map[String, Method](prefix + methodSym.name.toString -> >>> cls.getDeclaredMethod(methodSym.name.toString)) ++ >>> (if (returnType.typeSymbol.isClass && >>> returnType.typeSymbol.asClass.isCaseClass) { >>> getFlattenFields(returnType, prefix + >>> methodSym.name.toString + ".") >>> } else { >>> Map.empty[String, Method] >>> }) >>> } toMap >>> } >>> >>> println(getFlattenFields(typeOf[Person[Name]])) >>> println(getFlattenFields(typeOf[America])) >>> >>> >>> the result of above is: >>> >>> Map(age -> public int test.Reflect$Person.age(), name -> public >>> java.lang.Object test.Reflect$Person.name()) >>> Map(age -> public int test.Reflect$America.age(), name -> public >>> test.Reflect$Name test.Reflect$America.name(), name.last -> public >>> java.lang.String test.Reflect$Name.last(), name.first -> public >>> java.lang.String test.Reflect$Name.first()) >>> >>> the first line of the result is not my expectation, how can i get the >>> second line, but using " >>> println(getFlattenFields(typeOf[Person[Name]]))"? >>> >>> >>> Thanks very much >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "scala-language" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> > -- > You received this message because you are subscribed to the Google Groups > "scala-language" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "scala-language" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.