Ответ 1
Вы можете передать результат m.erasure
в Class[T]
:
class myclass[T] {
def something()(implicit m: Manifest[T]): Class[T] =
m.erasure.asInstanceOf[Class[T]]
}
Это отлично подходит для базовых (не общих) типов:
scala> new myclass[String]().something()
res5: Class[String] = class java.lang.String
Но обратите внимание, что произойдет, если я использую конструктор экземпляров типа List[String]
для T
:
scala> new myclass[List[String]]().something()
res6: Class[List[String]] = class scala.collection.immutable.List
Из-за стирания существует только один объект Class
для всех возможных экземпляров данного конструктора типов.
Изменить
Я не уверен, почему Manifest[T].erasure
возвращает Class[_]
вместо Class[T]
, но если бы мне пришлось спекулировать, я бы сказал, что это препятствует вам использовать методы на Class
, которые позволяют сравнивать два классы для равенства или отношения подтипа, так как эти методы дадут вам неправильные ответы, когда параметр Class
параметризуется с помощью созданного типичного типа.
Например,
scala> classOf[List[String]] == classOf[List[Int]]
res25: Boolean = true
scala> classOf[List[String]].isAssignableFrom(classOf[List[Int]])
res26: Boolean = true
Эти результаты могут удивить вас и/или привести к ошибке в вашей программе. Вместо того, чтобы сравнивать классы таким образом, вы обычно должны просто обходить Manifest
и сравнивать их, так как они имеют больше информации *:
scala> manifest[List[String]] == manifest[List[Int]]
res27: Boolean = false
scala> manifest[List[String]] >:> manifest[List[Int]]
res28: Boolean = false
Как я понимаю, Manifest
предназначены для замены Class
es для большинства случаев использования... но, конечно, если вы используете фреймворк, который требует Class
, выбора не так много. Я бы предположил, что наложение результата erasure
является всего лишь своего рода "признанием ответственности" за то, что вы используете худший продукт на свой страх и риск:)
* Обратите внимание, что, как сообщает документация для манифеста, эти явные операторы сравнения "должны рассматриваться только как аппроксимации, так как существует множество аспектов соответствия типов, которые не являются но адекватно представлены в манифесте".