Re: how can i reflect the instantiated return type of a generic type's method?
Daniel Armak <[email protected]> Sat, 12 Mar 2016 18:47:12 +0200
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CADtYB+=KqOBshojyFYdUtX76kPpxDfR=on7Qr-MbQ2NBf6tAdA@mail.gmail.com> |
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.