JDK5引入泛型,給我們編程帶來了很大的方便,它讓我們的類更加通用.但曾一段時間對java泛型中獨有的擦除概念,迷惑不解.什么是擦除?擦除的實質是什么?為什么要擦除?經過一段時間的研究后,總算有所體會,下面與大家分享一下,學習中的經驗.
個人理解擦除說的通俗一點就是轉型,就是將泛化的不確定類型,轉型到某一確定的類型,這一確定的類型我們稱之為邊界,這一轉型的過程就是擦除。這樣說你可能還不好理解,我來寫個例子,根據例子來剖析擦除的實質。
源代碼
public class Bootstrap {
public static void main(String[] args) {
List<Number> list = new ArrayList<Number>();
list.add(1);
list.add(new Float(2.1));
Number number = list.get(0);
}
}
反編譯后的代碼
public class Bootstrap
{

public Bootstrap()
{
}

public static void main(String args[])
{
List list = new ArrayList();
list.add(Integer.valueOf(1));
list.add(new Float(2.1000000000000001D));
Number number = (Number)list.get(0);
}
} 通過比較反編譯后發現,源代碼在編譯后產生的代碼中,并不存在泛型。它就像我們以前沒有泛型時,編寫的代碼一樣。原有的泛型信息并不存在,我們說它被擦除了,那被擦除成什么了呢?我們看Number number = list.get(0);這句代碼,當我們試圖從list中獲取元素時,java編譯器會自動的給我們進行強制轉型,這種轉型后的目標類都是Number,致使我們獲取的元素都是Number類型了,原有的類型Integer和Float都被擦除掉了,并沒有任何地方存儲了元素的確切類型,我們無法知道獲取元素的確切類型,只知道獲取的是個邊界類型Number。這就是java泛型的擦除實質。這兒也可以看出JAVA的泛型在運行時并不使用,它只在編譯的時候發揮作用。
為什么java會擦除泛型信息呢?其實這是可以理解的,因為在以前的JDK版本中,并不存在泛型這一概念,為了兼容以前的版本,讓新寫的泛型程序能在以前得版本上運行而采用了這種折中的辦法。
然而,由于泛型的不徹底,也給我們帶來了一定的困惑,其中最大的困惑就是,我們不能使用new 關鍵字來構造泛型.如new T();這樣做是不合法的編譯器無法通過。雖然說在現有的JDK版本上,編譯錯誤可以理解,但是著實讓人不爽.泛型中還存在其他的一些問題,有興趣的同學可以研究一下:http://www.ibm.com/developerworks/cn/java/j-jtp01255.html
個人理解擦除說的通俗一點就是轉型,就是將泛化的不確定類型,轉型到某一確定的類型,這一確定的類型我們稱之為邊界,這一轉型的過程就是擦除。這樣說你可能還不好理解,我來寫個例子,根據例子來剖析擦除的實質。
源代碼








反編譯后的代碼















為什么java會擦除泛型信息呢?其實這是可以理解的,因為在以前的JDK版本中,并不存在泛型這一概念,為了兼容以前的版本,讓新寫的泛型程序能在以前得版本上運行而采用了這種折中的辦法。
然而,由于泛型的不徹底,也給我們帶來了一定的困惑,其中最大的困惑就是,我們不能使用new 關鍵字來構造泛型.如new T();這樣做是不合法的編譯器無法通過。雖然說在現有的JDK版本上,編譯錯誤可以理解,但是著實讓人不爽.泛型中還存在其他的一些問題,有興趣的同學可以研究一下:http://www.ibm.com/developerworks/cn/java/j-jtp01255.html