您可以将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
这些结果可能会让您感到惊讶和/或导致您的程序出现错误。您通常不应以这种方式比较类,而应直接传递 Manifests 并比较它们,因为它们有更多信息*:
scala> manifest[List[String]] == manifest[List[Int]]
res27: Boolean = false
scala> manifest[List[String]] >:> manifest[List[Int]]
res28: Boolean = false
据我了解,Manifests 旨在取代 Classes 对于大多数用例...但当然,如果您使用的框架需要 Class,则没有太多选择。我认为强制转换erasure 的结果只是一种“承认责任”,您使用劣质产品需要您自担风险:)
* 请注意,正如documentation for Manifest 所说,这些清单比较运算符“应仅视为近似值,因为类型一致性的许多方面尚未在清单中充分表示。”