大數據系列修煉-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 evidence
從理論上講,創建出一個泛型數組是不可以的,因為沒有指明具體的數據類型,而在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
文章列表