Scala中获取Class的方式:
Scala中获取Type的方式:
Java和scala是基于JVM的,在虚拟机内部,并不关心泛型或类型系统。在JVM上,泛型参数类型T在运行时是被擦除掉的, 编译器把T当作Object来对待,所以T的具体信息是无法得到的。
Manifest是scala2.8引入的一个特质,用于编译器在运行时也能获取泛型类型的信息。为了使得在运行时得到T的信息,scala需要额外通过Manifest来存储T的信息,并作为参数用在方法的运行时上下文。
在引入Manifest的时候,还引入了一个更弱一点的ClassManifest,所谓的弱是指类型信息不如Manifest那么完整。
不过scala在2.10里用TypeTag替代了Manifest,用ClassTag替代了ClassManifest。
参考:http://hongjiang.info/
scala> class A
defined class A
scala> val a = new A
a: A = A@17a1e4ca
scala> a.getClass
res10: Class[_ <: A] = class A
scala> classOf[A]
res11: Class[A] = class A
上面显示了两者的不同,getClass方法得到的是Class[A]的某个子类,而classOf[A]得到是正确的Class[A],但是去比较的话,这两个类型是equals为true的:
scala> a.getClass == classOf[A]
res12: Boolean = true
这种细微的差别,体现在类型赋值时,因为java里的 Class[T]是不支持协变的,所以无法把一个Class[_ < : A] 赋值给一个 Class[A]
scala> val ab:Class[A] = a.getClass
<console>:12: error: type mismatch;
found : Class[?0] where type ?0 <: A
required: Class[A]
Note: ?0 <: A, but Java-defined class Class is invariant in type T.
Scala中获取Type的方式:
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> typeOf[List[Int]]
res6: reflect.runtime.universe.Type = scala.List[Int]
与classOf相比,typeOf返回的泛型信息更具体:
scala> classOf[List[Int]]
res8: Class[List[Int]] = class scala.collection.immutable.List
scala> classOf[List[Int]] == classOf[List[String]]
res9: Boolean = true
scala> typeOf[List[Int]] == typeOf[List[String]]
res10: Boolean = false
Java和scala是基于JVM的,在虚拟机内部,并不关心泛型或类型系统。在JVM上,泛型参数类型T在运行时是被擦除掉的, 编译器把T当作Object来对待,所以T的具体信息是无法得到的。
Manifest是scala2.8引入的一个特质,用于编译器在运行时也能获取泛型类型的信息。为了使得在运行时得到T的信息,scala需要额外通过Manifest来存储T的信息,并作为参数用在方法的运行时上下文。
def foo[T:Manifest] (x: List[T])
Manifest会记录T类型信息,在运行时就可以更准确的判断T。
在引入Manifest的时候,还引入了一个更弱一点的ClassManifest,所谓的弱是指类型信息不如Manifest那么完整。
不过scala在2.10里用TypeTag替代了Manifest,用ClassTag替代了ClassManifest。
参考:http://hongjiang.info/