【发布时间】:2015-01-09 22:52:28
【问题描述】:
假设我有:
class X
{
val listPrimitive: List[Int] = null
val listX: List[X] = null
}
我打印出Scala中每个方法的返回类型如下:
classOf[ComplexType].getMethods().foreach { m => println(s"${m.getName}: ${m.getGenericReturnType()}") }
listPrimitive: scala.collection.immutable.List<Object>
listX: scala.collection.immutable.List<X>
所以...我可以确定listX 的元素类型是X,但是有没有办法通过反射确定listPrimitive 的元素类型实际上是java.lang.Integer? ...
val list:List[Int] = List[Int](123);
val listErased:List[_] = list;
println(s"${listErased(0).getClass()}") // java.lang.Integer
注意。由于 JVM 类型擦除,这似乎不是问题,因为我 可以 找到 List 的 types 参数。看起来scala编译器丢弃了这个类型信息IFF参数类型是 java.lang.[numbers] 。
更新:
由于以下实验,我怀疑此类型信息是可用的。假设我定义:
class TestX{
def f(x:X):Unit = {
val floats:List[Float] = x.listPrimitive() // type mismatch error
}
}
并且 X.class 是通过 jar 导入的。完整的类型信息必须在 X.class 中可用,这样这种情况才能正确编译失败。
更新2:
假设您正在为 Java 序列化库编写 scala 扩展。你需要实现一个:
def getSerializer(clz:Class[_]):Serializer
根据是否需要做不同事情的函数:
clz==List[Int] (or equivalently: List[java.lang.Integer])
clz==List[Float] (or equivalently: List[java.lang.Float])
clz==List[MyClass]
我的问题是我只会看到:
clz==List[Object]
clz==List[Object]
clz==List[MyClass]
因为 clz 以 clz.getMethods()(i).getGenericReturnType() 的形式提供给此函数。
从 clz:Class[_] 开始,如何恢复丢失的元素类型信息?
我不清楚 TypeToken 是否会对我有所帮助,因为它的用途:
typeTag[T]
要求我提供 T(即在编译时)。
所以,一个解决方案的路径...给定一些 clz:Class[_],我可以确定其方法返回类型的 TypeTokens 吗?显然,这是可能的,因为此信息必须包含在 .class 文件中(某处),以便 scala 编译器正确生成类型不匹配错误(见上文)。
【问题讨论】:
标签: scala reflection scala-reflect