热门
1.什么是泛型擦除我们都知道Java的泛型是伪泛型,即编译期间所有的泛型信息都会被擦除,如我们代码定义了:List和List,但是对于JVM而言,看到的只有List,由泛型附加的类型信息对于JVM而言是看不到的。代码说明如下:1.1 原始类型擦除后相等public class Test { public static void main(String[] args) { ArrayList list1 = new ArrayList(); list1.add("abc"); ArrayList<Integer> list2 = new ArrayList<Integer>(); list2.add(123); System.out.println(list1.getClass() == list2.getClass()); } }在这个例子中,我们定义了两个ArrayList数组,不过一个是ArrayList泛型类型的,只能存储字符串;一个是ArrayList泛型类型的,只能存储整数,最后,我们通过list1对象和list2对象的getClass()方法获取他们的类的信息,最后发现结果为true。说明泛型类型String和Integer都被擦除掉了,只剩下原始类型。 1.2 反射添加的元素被擦除 public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { ArrayList list = new ArrayList(); list.add(1); //这样调用 add 方法只能存储整形,因为泛型类型的实例为 Integer list.getClass().getMethod("add", Object.class).invoke(list, "asd"); for (int i = 0; i < list.size(); i++) { // 输出1 asd System.out.println(list.get(i)); } } 如果直接调用add()方法,那么只能存储整数数据,不过当我们利用反射调用add()方法的时候,却可以存储字符串,这说明了Integer泛型实例在编译之后被擦除掉了,只保留了原始类型。
ArrayList<Integer> list2 = new ArrayList<Integer>(); list2.add(123); System.out.println(list1.getClass() == list2.getClass()); }
}在这个例子中,我们定义了两个ArrayList数组,不过一个是ArrayList泛型类型的,只能存储字符串;一个是ArrayList泛型类型的,只能存储整数,最后,我们通过list1对象和list2对象的getClass()方法获取他们的类的信息,最后发现结果为true。说明泛型类型String和Integer都被擦除掉了,只剩下原始类型。
1.2 反射添加的元素被擦除
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { ArrayList list = new ArrayList(); list.add(1); //这样调用 add 方法只能存储整形,因为泛型类型的实例为 Integer list.getClass().getMethod("add", Object.class).invoke(list, "asd");
for (int i = 0; i < list.size(); i++) { // 输出1 asd System.out.println(list.get(i)); } }
如果直接调用add()方法,那么只能存储整数数据,不过当我们利用反射调用add()方法的时候,却可以存储字符串,这说明了Integer泛型实例在编译之后被擦除掉了,只保留了原始类型。