基本上,我希望有一个由类型对象索引的Map。在这种情况下,我试图使用Class作为“类型类型”。
以下代码:
class SuperClass {}
val typemap = new HashMap[Class[_ <: SuperClass], SuperClass]
def insertItem1[T <: SuperClass] (item : T) = typemap += classOf[T] -> item
def insertItem2[T <: SuperClass] (item : T) = typemap += item.getClass -> item
不编译,因为(1)classOf [T]显然无效:
error: class type required but T found
和(2)item.getClass的类型错误:
Type mismatch, expected: Class[_ <: SuperClass], actual: Class[_]
我认为有两种方法可以做到这一点:
要么删除类型要求,只使用Class [_]
或使用Manifest而不是Class(不知道如何做到这一点,欢迎任何例子)
但更一般地说,为什么classOf [T]无效,如何获得参数化类型的类对象?
更新:我发现我可以使用item.getClass.asInstanceOf[Class[T]]
来获取类对象。首先,这很难看。对于两个,它没有多大帮助,因为稍后在代码中我有这样的功能:
def isPresent[T <: SuperClass] = typemap contains classOf[T]
显然,我可以在insertItem
中使用asInstanceOf方法,并将该类作为参数传递给isPresent
。还有更好的方法吗?
答案 0 :(得分:2)
您可以使用清单来实现此目的:
class TypeMap extends HashMap[Class[_], Any] {
def putThing[T](t: T)(implicit m: Manifest[T]) = put(m.erasure, t)
}
val map = new TypeMap
map.putThing(4)
map.get(classOf[Int]) // returns Option[Any] = Some(4)
您正在通过擦除丢失类型,因此您需要使用Manifest将隐式参数添加到包含类名称的putThing中。
答案 1 :(得分:1)
问题再一次是泛型在运行时不可用。编译器负责确定T
是什么,但它不能,因为它只在运行时知道。
您可以使用清单获取该信息:What is a Manifest in Scala and when do you need it?。