文章目录
一、Java泛型的引入
咱们现在使用集合框架通常的方式是
List<Integer> list = new ArrayList<Integer>();
Set<Integer> set = new HashSet<Integer>();
Map<Integer, String> map = new HashMap<Integer, String>();
在这里用于指定类型的<E>
被称为泛型,泛型是jdk1.5时引入的新特性。在jdk1.5之前是没有泛型的,那么在这之前是如何使用集合框架的呢?
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
当我们需要从list
当中取出元素时需要这样做:
Object item = list.get(0);
因为我们没有指定欲元素类型,所以默认是Object
类型,那么如果我们想要获得一个Integer
类型,就必须进行强制转换:
Integer item = (Integer)list.get(0);
在理想状态下(list
当中的元素都是Integer
类型),这种操作是不存在任何问题的,但是如果出现如下情况,程序便会出现java.lang.ClassCastException
异常:
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add("a");
for (int i = 0; i < list.size(); i++) {
Integer item = (Integer)list.get(i);
System.out.println(item);
}
--------------------------------------------------------------
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
原因就是因为list
中元素的类型是Object
类型,而Integer
和String
都是Object
的子类,所以都是可以插入list
当中的,但是String
类型是无法转化成Integer
类型的数据,因此会存在潜在的异常。而用户的操作往往是不可预测的,所以这个潜在的异常可能会引起非常严重的后果。
而泛型的出现,完美的解决了这个问题。
泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型(即当输入的数据类型和指定的类型不相符时会直接报错,直接无法通过编译)。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
二、泛型的虚伪性
为什么Java泛型被称为伪泛型
在1.5之前是没有泛型的,那么在原本的基础上增加泛型这一特性,如何保证新旧特性的兼容性就成了一个比较大的问题。
在这一问题上jdk使用泛型擦除的方式来完成。
泛型擦除:在编译期间,所有的泛型信息都会被擦掉,即写的代码是List<Integer>
,但编译过后的字节码是List<Object>
,和没有泛型的效果是一样的。
List<Integer> integerList = new ArrayList<Integer>();
List<String> stringList = new ArrayList<String>();
System.out.println(integerList.getClass()); // class java.util.ArrayList
System.out.println(stringList.getClass()); // class java.util.ArrayList