问题是您使用的 Java 反射 API 无法解决 JVM 的“类型擦除”问题,因为无法使用它找出实际的泛型类型。
幸运的是,即将到来的 Scala 2.10 版本实现了新的反射 API,解决了类型擦除问题。但是由于 2.10 还没有发布,API 还没有标准化,也没有记录。最好的办法是使用调试器之类的工具深入研究它,并在此处提出更具体的问题。
在 Scala 2.10-M5 中,您可以访问 API,如下所示:
scala> reflect.runtime.universe.typeOf[(Int, String)]
res0: reflect.runtime.universe.Type = (Int, String)
scala> reflect.runtime.universe.typeOf[(Int, String)].typeArguments
res1: List[reflect.runtime.universe.Type] = List(Int, String)
scala> reflect.runtime.universe.typeOf[(Int, String)].typeArguments.head
res2: reflect.runtime.universe.Type = Int
更新#1
以下函数显示了如何获取实例类型:
scala> import reflect.runtime.universe._
import reflect.runtime.universe._
scala> def typeOf[T : TypeTag](x : T) = reflect.runtime.universe.typeOf[T]
typeOf: [T](x: T)(implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.Type
scala> typeOf(Seq((1,"sldf"),(20,"sldkfjew")))
res0: reflect.runtime.universe.Type = Seq[(Int, String)]
事实上,这一切都基于[T : TypeTag]
告诉编译器神奇地创建对传递的类型的反射的隐式实例的部分。
更新#2
scala> class TupleReflection(val tuple: Tuple2[Int, String])
defined class TupleReflection
scala> import reflect.runtime.universe._
import reflect.runtime.universe._
scala> typeOf[TupleReflection].member(newTermName("tuple")).typeSignature
res6: reflect.runtime.universe.Type = => (scala.Int, String)
scala> typeOf[TupleReflection].members
res7: Iterable[reflect.runtime.universe.Symbol] = List(constructor TupleReflection, value tuple, value tuple, method $asInstanceOf, method $isInstanceOf, method synchronized, method ##, method !=, method ==, method ne, method eq, constructor Object, method notifyAll, method notify, method clone, method getClass, method hashCode, method toString, method equals, method wait, method wait, method wait, method finalize, method asInstanceOf, method isInstanceOf, method !=, method ==)
scala> typeOf[TupleReflection].members.view.filter(_.isValue).filter(!_.isMethod).toList
res16: List[reflect.runtime.universe.Symbol] = List(value tuple)