java 泛型數(shù)組初始化
public class GenericArray<T> {
private T[] arr;
public GenericArray(){
arr = new T[10]; //編譯錯(cuò)誤
}
}
使用這樣的方式初始化java的數(shù)組會(huì)出錯(cuò)哺壶,因?yàn)閖ava不支持泛型數(shù)組变骡。按照我的理解芭逝,java 初始化數(shù)組時(shí)候旬盯,需要知道數(shù)組的確切類型台妆,但是泛型是編譯后擦除的。所以運(yùn)行時(shí)胖翰,無(wú)法知道數(shù)組的確切類型接剩。所以java不支持以 new T[] 方式初始化一個(gè)數(shù)組。
如果想進(jìn)行初始化萨咳,可以通過(guò)這樣的方式
T[] arr=(T[]) new Object[10];
scala的泛型數(shù)組
那么同樣的場(chǎng)景懊缺,在scala中如何實(shí)現(xiàn)呢
class ScalaGenericArray[T]{
val arr: Array[T] = new Array[T](10)
}
object ScalaGenericArray{
def main(args: Array[String]): Unit = {
val arr = new ScalaGenericArray[String]
}
}
看起來(lái)很自然,但是在運(yùn)行時(shí)候會(huì)報(bào)錯(cuò):
Error:(9, 23) cannot find class tag for element type T
val arr: Array[T] = new Array[T](10)
原因和java的一樣培他,虛擬機(jī)中鹃两,泛型相關(guān)的類型信息會(huì)被擦除,所以無(wú)法將T解釋成實(shí)際類型String
那么如何做呢舀凛,此處我們需要將類型的信息以一個(gè)參數(shù)的方式傳進(jìn)去
class ScalaGenericArray[T](implicit classTag:ClassTag[T] ){ //讓編譯器幫我們傳入類型信息
val arr: Array[T] = new Array[T](10)
}
object ScalaGenericArray{
def main(args: Array[String]): Unit = {
val arr = new ScalaGenericArray[String]
}
}
- 感覺這種方式有點(diǎn)類似于java為了獲取一個(gè)泛型的信息俊扳,將類以參數(shù)的形式傳入函數(shù)參數(shù)中
public <T> T test(Class<T> clazz) {
System.out.println(clazz);
//...
}
當(dāng)然此處的ClassTag也可以使用Manifest,但是在scala 2.10.0后就不推薦使用了
這樣寫比較復(fù)雜猛遍,scala也提供另一種簡(jiǎn)單的方式,上下文界定
class ScalaGenericArray[T: ClassTag] {//此處不再需要提供參數(shù)
val arr: Array[T] = new Array[T](10)
}
object ScalaGenericArray {
def main(args: Array[String]): Unit = {
val arr = new ScalaGenericArray[String]
}
}
這是scala的語(yǔ)法糖,T:ClassTag 告訴scala存在一個(gè)類型為ClassTag[T] 的隱式參數(shù)