class S
class A extends S
class B extends S
class ClassWithTypeParameter[+T]
val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]
如何确定用于值 a 的类型参数的子类的类型?
class S
class A extends S
class B extends S
class ClassWithTypeParameter[+T]
val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]
如何确定用于值 a 的类型参数的子类的类型?
你不能因为类型擦除。但是,我认为您这样做的尝试是由于误解造成的。
在你的程序中,有一个引用,a
这个引用的类型是ClassWithTypeParameter[S]
. 那。是。全部。编译器可以知道使用此引用可以做什么。这些类型纯粹是为编译器而存在的。事实上,在运行时,a
被分配给一个值ClassWithTypeParameter[A]
是无关紧要的。
一种近似的方法(受擦除限制)是使用清单(在 2.10 中称为其他东西):
class ClassWithTypeParameter[+T: Manifest] { def erasure = manifest[T].erasure }
然后你可以打电话erasure
给你java.lang.Class
。正如我所说,这是有限的。类与类型不同,没有办法区分,例如ClassWithTypeParameter[List[Int]]
,ClassWithTypeParameter[List[Double]]
以下是一个坏主意(就像反射的大多数用途一样),但它有效:
class ClassWithTypeParameter[+T: Manifest] {
def paramIs[V: Manifest] = manifest[T] == manifest[V]
}
这给了我们:
scala> val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]
a: ClassWithTypeParameter[S] = ClassWithTypeParameter@6493c09c
scala> a.paramIs[A]
res0: Boolean = true
scala> a.paramIs[S]
res1: Boolean = false
scala> a.paramIs[B]
res2: Boolean = false
和:
scala> val i = new ClassWithTypeParameter[List[Int]]
i: ClassWithTypeParameter[List[Int]] = ClassWithTypeParameter@260702ee
scala> i.paramIs[List[Int]]
res3: Boolean = true
scala> i.paramIs[List[Double]]
res4: Boolean = false
您可以使用' sparamSubtypeOf
和.paramSupertypeOf
Manifest
<:<
>:>
在 Scala 2.10(里程碑 4 或更高版本)中,有一种更灵活的方式来获取类型:
class ClassWithTypeParameter[+T: TypeTag] {
def paramType = reflect.runtime.universe.typeTag[T].tpe
}
现在您可以编写诸如a.paramType.parents
获取直接超类型之类的东西。