Предположим, у меня есть:
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
NB. Кажется, это не проблема из-за стирания типа JVM, поскольку я могу найти параметр типов в списке. Похоже, что компилятор scala отбрасывает эту информацию о типе, если тип параметра java.lang.[numbers] .
ОБНОВИТЬ:
Я подозреваю, что информация об этом типе доступна из-за следующего эксперимента. Предположим, я определяю:
class TestX{
def f(x:X):Unit = {
val floats:List[Float] = x.listPrimitive() // type mismatch error
}
}
и X.class импортируется через банку. Полная информация о типе должна быть доступна в X.class, чтобы в этом случае не удалось правильно скомпилировать.
ОБНОВЛЕНИЕ2:
Представьте, что вы пишете расширение scala для библиотеки сериализации Java. Вам необходимо реализовать:
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 правильно генерировал ошибки несоответствия типов (см. выше).