假设我需要提供一个带有java.lang.Class
对象的方法,该对象表示某个父类A
的子类。我需要从另一个方法执行此操作,该方法具有一个泛型参数,其上限类型绑定到A
。
我认为这可行:
class A
def f(clazz: java.lang.Class[_ <: A]) = ()
def g[T <: A : Manifest] = f(classManifest[T].erasure)
但事实并非如此:
<console>:9: error: type mismatch;
found : java.lang.Class[_$1(in method g)] where type _$1(in method g)
required: java.lang.Class[_ <: A]
def g[T <: A : Manifest] = f(classManifest[T].erasure)
^
为什么编译器不能确定T
确实是A
的子类?无论如何我能帮忙吗?或者我应该以完全不同的方式处理这个问题?
答案 0 :(得分:3)
它不起作用,因为erasure
has the type Class[_]
,这是一种存在类型。这意味着Class
对象erasure
由某种类型进行参数化,但这与哪种确切类型并不重要。 erasure
上面没有Class[T]
类型。
方法f
需要Class[_ <: A]
类型的参数,该参数是已知的某种类型A
的子类型。上限不一定由上面的Class[_]
类型确保。
解决方案:您知道erasure
具有正确的类型,只是此类型未在ClassManifest
对象中公开。简单地投下它:
classManifest[T].erasure.asInstanceOf[Class[A]]
编辑:
如果您有B
的子类A
:
scala> class A
scala> def f(clazz: java.lang.Class[_ <: A]) = ()
scala> def g[T <: A : Manifest] = f(classManifest[T].erasure.asInstanceOf[Class[A]])
scala> g[A]
scala> class B extends A
scala> g[B]