Type与Class、ClassTag与TypeTag

Scala中获取Class的方式:
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/
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值