java泛型 擦除的補償

2021-09-01 09:11:40 字數 2491 閱讀 6122

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...