文章出處

大數據系列修煉-Scala課程46


核心內容:
1、scala中ClassTag、Manifest、ClassManifest、TypeTag的具體應用


1>泛型T在編寫與編譯的時候不能確定出具體的數據類型,但是虛擬機在運行的時候必須要指定出T具體的數據類型,因為我們的scala是
運行在Java虛擬機上的,而ClassTag、Manifest、ClassManifest、TypeTag會幫助我們存儲T運行時具體的數據類型,并把運行時存儲
的這個數據類型通過反射的方式傳遞給虛擬機。
2>ClassTag主要是在運行時存儲那些在編譯時無法確定的比較high-level級別的信息。
3>泛型在Java虛擬機上面實際運行的時候,泛型的信息會被擦除掉,虛擬機只認識Array[String]這種基本類型數據,并不認識泛型
Array[T]。
4>從理論上講,創建出一個泛型數組是不可以的,因為沒有指明具體的數據類型,而在scala中運行的時候數組必須要有具體的

數據類型。

本篇博客將詳細介紹scala中ClassTag、Manifest、ClassManifest、TypeTag的由來和重要應用:
實例程序1:

object App {      def main(args:Array[String]):Unit=         {        val aa = new A[String,Double,Int]("zhangsan",98.8,24)      aa.fun()   }}class A[F,S:ClassTag,T:ClassTag](val first:F,val second:S,val third:T)(implicit m:ClassTag[F]){   def fun() = println(first+"\t"+second+"\t"+third)}

在上面的程序中,泛型F,S,T在編寫與編譯的時候并不能確定出具體的數據類型,當我們程序在運行的時候,ClassTag會幫助我們隱式的
存儲F,S,T對應的String、Double,Int類型。并在運行的時候將這些數據類型通過反射的方式傳遞給虛擬機。
然而,在上面的程序中,并不需要ClassTag機制,因為String、Double是基本的數據類型。引出實例程序2:

實例程序2:構造泛型的數組

object App {      def main(args:Array[String]):Unit=         {        def mkArray[T](first:T,second:T) =      {         val arr = Array[T](first,second) //Array[T]Java虛擬機不能夠識別         arr      }   }}

對于上面的程序,會報錯:
No ClassTag available for T
not enough arguments for method apply: (implicit evidence21:scala.reflect.ClassTag[T])Array[T]inobjectArray.Unspecifiedvalueparameterevidence21.
從理論上講,創建出一個泛型數組是不可以的,因為沒有指明具體的數據類型,而在scala中運行的時候數組必須要有具體的
數據類型。
對于上面的問題,scala中引入了ClassTag幫我們解決。

實例程序3:ClassTag在構造泛型數組中的應用

object App {      def main(args:Array[String]):Unit=         {        //ClassTag幫我們存儲T運行時具體的數據類型      def mkArray[T:ClassTag](first:T,second:T) =      {         val arr = Array[T](first,second)         arr      }      val aa = mkArray[String]("Spark","Hadoop")      aa.foreach(println)   }}/** * Spark * Hadoop */

在上面的程序中,ClassTag會幫助我們存儲T運行時具體的數據類型。
對于實例3來說,還可以這么寫:

實例程序4:ClassTag在構造泛型數組中的應用

object App {      def main(args:Array[String]):Unit=         {        //ClassTag幫我們存儲T運行時具體的數據類型      def mkArray[T](first:T,second:T)(implicit m:ClassTag[T]) =      {         val arr = Array[T](first,second)         arr      }      val aa = mkArray[String]("Spark","Hadoop")      aa.foreach(println)   }}/** * Spark * Hadoop */

實例程序5:ClassTag的應用舉例

object App {      def main(args:Array[String]):Unit=         {        //同理,ClassTag幫我們隱式的存儲T運行時的具體的數據類型      def mkArray[T:ClassTag](eles:T*) = Array(eles:_*)      val arr = mkArray[Int](10,20,30)      arr.foreach(println)   }}

實例程序6:ClassTag的應用舉例

object App {      def main(args:Array[String]):Unit=         {        def manif[T](x:List[T])(implicit m:ClassTag[T])=      {        if(m <:< manifest[String])          println("List Strings")        else          println("Some other type")      }      manif(List("Spark","Hadoop")) //List Strings      manif(List("Scala",3)) //Some other type   }}

如有問題,歡迎留言指正!

就愛閱讀www.92to.com網友整理上傳,為您提供最全的知識大全,期待您的分享,轉載請注明出處。
歡迎轉載:http://www.kanwencang.com/bangong/20161116/54157.html

文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()