假设我有:
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 编译器正确生成类型不匹配错误(见上文)。