1、為什麼需要補償
由於擦除,我們無法直接得到泛型引數的型別資訊。所以任何執行時需要型別資訊的操作都不能工作。
例如:(1)無法使用instanceof關鍵字
(2)無法通過new操作建立乙個泛型引數型別的物件
(3)無法建立泛型陣列
public class erase//編譯錯誤
t var = new t();//編譯錯誤,這裡不能直接建立物件的原因還有無法確認t有預設的構造器
t array = new t[10];//編譯錯誤
}}
2、如何補償(如何獲得丟失的型別資訊)
解決方法之一是可以使用class物件來獲得型別資訊。
例如:(1)使用動態的isinstance代替instanceof
class a{}
class b extends a{}
public class classtypecapture
public boolean f(object arg)
}
(2)使用newinstance()方法建立物件
class classasfactorycatch(exception e)
}}
但是對於沒有預設構造器的類,無法用newinstance()來建立物件
對於沒有預設構造器的類可以使用工廠方法模式
//工廠介面,強制工廠實現create方法,這個方法用來產生物件
inte***ce factoryi
//產生integer物件的工廠,使用直接實現介面的方式來實現
class intege***ctory implements factoryi
}//使用內部類的方式達到對介面的實現
class widget }}
//泛型型別通過接收乙個工廠物件來建立t型別的物件
class foo2
}
(3)建立泛型陣列
建立泛型型別陣列:
如果是要建立泛型型別的陣列,例如建立乙個generic型別的陣列(也就是建立generic),那麼唯一的辦法時建立擦除型別的陣列然後轉型:
generic gia =(generic) new generic[10];
建立泛型型別引數的陣列:
一般情況如果需要用到泛型引數型別的陣列那麼使用arraylist。
例如:
public class listofgenerics
public t get(int index)
}
除了arraylist還有下面三種方法:
一是使用object陣列,在返回時進行轉型,依然無法返回乙個t型別的陣列,但是可以返回t型別的單個元素值。
class genericarray
public void put(int index,t item)
//在返回時進行轉型
public t get(int index)
//這個即使轉型返回的依然是object
public t rep()
public static void main(string args)
另一種是使用class物件,這是最好的方式,裡面的方法都能很好的使用。
class genericarraywithtypetoken
public void put(int index,t t)
public t get(int index)
public t rap()
}
這種方法關鍵就是使用class物件和array.newinstance()方法,上面例項中的**會有警告,警告內容是object轉換成t可能會不安全,也就是說array.newinstance()返回的應該是個object,那麼能不能直接在array初始化時使用object然後轉型為t呢?答案是否定的。可以看到array.newinstance()方法中有乙個引數是class物件,也就是說它可以使用class物件來恢復被擦除的資訊,而直接使用object然後轉型也無法返回確切型別的陣列。
例子:
public class genericarrays
public void put(int index,t item)
//public t get(int index)
public t rep()
public static void main(string args)
}
泛型擦除補償
由於在使用泛型的時候,將會擦除型別引數,而只保留原始型別。所以在使用泛型時,我們不能使用new t 也不能使用instanceof,因為這兩類操作要知道確切的型別。此問題的解決方案有三種 設計模式的使用 簡單工廠 最簡單 工廠方法 最靈活 模板方法 最簡捷 1.簡單工廠 在此方法中,將型別作為引數,...
Java泛型擦除
class person public class test else 上面的例子執行 equal這裡列印出equal的原因,list和list list擦除後的型別都是list,沒有任何區別。其實泛型的class物件都是相同的,泛型化不會改變class屬性的返回值。再看看下面的例子 private...
Java中的泛型擦除
有著樣一種泛型的用法 class selfbounded 這就像兩面鏡子,兩個鏡子之間永遠看不到頭,selfbounded接受t作為泛型引數,t又由擁有t引數的selfbounded作為邊界限定。這就叫做迴圈泛型,為了理解這種命名,看下面一段 class generictype class curi...