一、ClassTag 、Manifest、ClassManifest、TypeTag代碼實戰
package ce.scala.zhong
object Multiple_Bounds_46 {
def main(args: Array[String]): Unit = {
//常見寫法(推薦)
def arrayMake[T : Manifest](first : T, second : T) = { //創建泛型數組,理論上不可以,因爲沒有指定具體的類型。運行時,數組必須有具體的類型。
//Array只是Scala的一個普通的類,在虛擬機中,泛型相關的類型信息是被抹掉的。只會有一個arrayMake方法,卻要處理所有類型T
//Manifest來幫我們存儲運行時的T的具體信息,實際運行時,作爲參數用在方法運行的上下文中。當然這個是隱式的過程
//[T : Manifest]是Manifest上下文界定。有這樣的隱式值Manifest[T]來輔助構建Array[T],從而確定數組類型
val r = new Array[T](2)
r(0) = first
r(1) = second
r
}
//原始寫法(不推薦)
def manif[T](x : List[T])(implicit m : Manifest[T]) = {
if(m <:< manifest[String]) println("List String") //<:<意思是m是manifest[String]的類型
else println("some other type")
}
manif(List("Spark", "Hadoop")) //會隱式傳入Manifest[String]的對象參數
manif(List(1,2))
manif(List("scala", 3))
}
}
輸出:
List String
some other type
some other type
class A[T]
val m = manifest[A[String]]
println(m)
val cm = classManifest[A[String]]
println(cm)
輸出:
ce.scala.zhong.A[java.lang.String]
ce.scala.zhong.A[java.lang.String]
ClassTag:
import scala.reflect.ClassTag //ClassTag最常用
def mkArray[T : ClassTag](elems : T*) = Array[T](elems : _*)
//ClassTag在運行時指定在編譯時無法確定的比較high-level級別的類別的信息(不包括static的,但這已經足夠了)
//JVM不認識Array[T],只認識Array[Int]或者Array[String]
mkArray(42,13).foreach(println)
mkArray("Chinese", "Germany", "Brazil").foreach(println)
輸出:
42
13
Chinese
Germany
Brazil
參考資料來源於大數據夢工廠 深入淺出scala 第46講 由王家林老師講解