Java 的泛型是伪泛型, 也就是骗骗编译器的。运行期的泛型类型,被擦除了,因此,在运行期,ArrayList<String> 和 ArrayList<int> 是相同的类型。
要证明是伪泛型,非常简单。看下面代码:
List<Integer> li = new ArrayList<Integer>();
List<Float> lf = new ArrayList<Float>();
boolean issame = li.getClass() == lf.getClass();
System.out.println(issame);//true
伪泛型会导致一些陷阱:
public static void main(String[] args) throws Exception {
List list = new ArrayList();
list.add("hello");
list.add("world");
List<Integer> intlist = list;
for (int i = 0; i < intlist.size(); i++) {
System.out.println(intlist.get(i)*100);
}
}
上述代码编译通过,但是运行时 intlist.get(i)*100 会报错,很明显 intlist 中的元素是无法进行乘法运算的,导致报错。
public static void main(String[] args) throws Exception {
// string集合的集合
List<ArrayList<String>> array_string_list = new ArrayList<ArrayList<String>>();
// 原始的集合 指向 string集合的集合
List arry = array_string_list;
ArrayList<String> lst_string = new ArrayList<String>();
lst_string.add("abcde");
// 原始集合可以不受限制的賦值任何集合,甚至是任何对象,反正最终都是变成Object对象
arry.add(lst_string);
ArrayList<Integer> lst_int = new ArrayList<Integer>();
lst_int.add(10);
// 原始集合可以不受限制的賦值任何集合
arry.add(lst_int);
// arry即array_string_list,有2个元素,第一个元素是string的泛型集合,第二个元素是int的泛型集合。
// 形成混乱,导致运行出错
System.out.print(array_string_list.size());// 2个元素
System.out.print(array_string_list.get(1).get(0));//运行时遇到转型错误。
}
同理,上面的代码在最后一行也会导致运行出错。所以编程的时候,要注意伪泛型的陷阱。
参考:《疯狂 Java》