Scala之ClassTag、Manifest、ClassManifest、TypeTag的关系

笔者在阅读Spark源码时,发现源码处大量地方用到ClassTag,一开始还无法理解其中的含义,后面慢慢查询与学习,整理出部分的内容。

在Scala中应用大量的数组,按照Scala的语法来说是不能创建泛型数组,因为Scala编译时必须要确定它的类型,否则编译都不能通过,但是Scala中引入了Manifest,Manifest可以有效解决这个问题

下面先来看个案例:

object demo {
  def main(args: Array[String]): Unit = {
    arrMake(2,".abc").foreach(print)
    println
    listMake(List("string","strings"))
    listMake(List(3,"string"))
    listMake(List(3,4))
  }
  //方式一
  def arrMake[T:Manifest](a: T, b: T):Array[T] = {
    val arr = new Array[T](2)
    arr(0) = a
    arr(1) = b
    arr
  }
  //方式二
  def listMake[T](x : List[T])(implicit m:Manifest[T]) = {
    if (m == manifest[String]) println("List String")
    else println("other type")
  }
}
打印结果:
2.abc
List String
other type
other type

如上图所示,当调用方法传递参数执行时,ClassTag会把参数类型记住,其实ClassTag就是隐式值,将类型传递给T,就是就隐式转换最重要的工作。

Manifest(上下文界定)特点:

  • 1)Array在Scala中是一个原生的数组,所以编译时并不会有过多的辅助的处理
  • 2)通过Manifest可以创建Array泛型类型的创建,即可以帮助Array提供确认泛型的类型(这就是隐式值)
  • 3)Manifest会存储运行时实际的类型,然后运行时作为参数传递
  • 4)泛型类型在运行时具体的类型是看不到的,被抹掉了
  • 5)隐式是一个难点、重点,隐式是自动判断类型,且进行传递的一个过程

ClassManifest

  • 和Manifest具有相同的作用,但是获取信息方面比Manifest弱一些

ClassTag :

  • 1)在Spark中的实际编码中ClassTag用的比较频繁,在隐式转换中具有非常重要的作用
  • 2)ClassTag最重要的也是指定在运行时泛型的类型(编译时无法识别的type)

总结:

1、Manifest有一些弱点,在判断指定路径方面的class的类型时会出现有误,所以用ClassTag代替Manifest,用TypeTag代替ClassManifest

2、TypeTag要比ClassTag更加强大(在实际应用中ClassTag更加广泛)

3、所有在JVM上运行的泛型的类型是被抹掉的,虚拟机根本不知道是什么类型

4、在实际的开发中经常使用上面案例中中的第一种方式应用泛型类,但在实际的编译中会形成第二种的方式运行

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值