JDK1.5增加的新特性裡面有一個就是泛型。對於泛型的評價,褒貶不一,廢話不多說,先來看看他的原理。
泛型是提供給javac編譯器使用的,可以限定集合中的輸入類型,讓編譯器攔截來源程式中的非法輸入,編譯器編譯帶類型說明的集合時會去掉類型資訊,對於參數化得泛型型別,getClass()方法的傳回值和原始類型完全一樣。
對於下面這個來源程式:
public class Oliver {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("str1");
list.add("str2");
String str = list.get(0);
}
}
編譯成Oliver.class後反編譯的內容:
public class Oliver {
public Oliver() {
}
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("str1");
list.add("str2");
String str = (String) list.get(0);
}
}
也就是說java的泛型只是在編譯器做了參數限制,其實對效能並沒有什麼最佳化!
由於編譯產生的位元組碼會去掉泛型的類型資訊,只要能跳過編譯器,就可以往某個泛型集合中加入其它的類型資料。
下面代碼展示利用反射機制跳過編譯器檢查:
public class Oliver {
public static void main(String[] args) throws Exception {
ArrayList<Integer> list = new ArrayList<Integer>();
list.getClass().getMethod("add", Object.class).invoke(list, "ssss");
System.out.println("list:" + list.get(0));
}
}
輸出結果:
list:ssss
對於java泛型,Bruce Ecke(Thinking in Java作者)曾經給出這樣的評論:
Guess what. I really don't care. You want to call it "generics," fine, implement something that looks like C++ or Ada, that actually produces a latent typing mechanism like they do. But don't implement something whose sole purpose is to solve the casting problem in containers, and then insist that on calling it "Generics." Of course, Java has long precedence in arrogantly mangling well- accepted meanings for things: one that particularly stuck in my craw was the use of "design pattern" to describe getters and setters. In JDK 1.4 we were told some lame way to use assertions which was a backward justification for them being disabled by default. JDK 1.4 also had to invent its own inferior logging system rather than using the openly created, well-tested and well-liked Log4J. And we've also been told many times about how Java has been as fast or faster than C++, or about how one or another feature is great and flawless. I point to the threads implementation which has had major changes quietly made from version to version with not so much as a peep of apology or admission that "hey, we really screwed up here." Or maybe I was just not on that particular announcement list.