需求描述:
需要往List类型的集合中添加Integer或Long或其他类型的数据。如何实现这个需求呢?
分析:理解泛型擦除,反射的应用
泛型擦除,先看下List类的源码,public interface List<E> extends Collection<E> {}
,可以看到List中用到了泛型。所谓的泛型擦除,即泛型的检查是发生在编译期,而经过编译后生成.class文件中是显式地指定了List的类型为某一类型(如果不加泛型,那该集合可以存储任意类型)。例如,.java文件中有一段代码是List list = new ArrayList<>();在编译期,往该list集合add进某个元素,是要做类型检查的,检查该元素是否为指定的泛型。而经过编译期后,就没有泛型的存在了,就像平时定义的集合一样,就是一个List,而不是List。这个现象就是我理解的泛型擦除。
解决:回归到需求,如何往List类型的集合中添加Integer类型的数据呢?其实就是要越过泛型的数据类型检查,也就是越过编译器的类型检查,到了运行期,通过反射的方式往List中add其他类型的元素。
代码如下:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class Type {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
List<String> list =new ArrayList<>();
list.add("abc");
Class<? extends List> c = list.getClass();
Method method=c.getMethod("add",Object.class);
method.invoke(list,123);
Object s = list.get(1);
System.out.println(s.getClass());
List arr = new ArrayList<>();
arr.add("asdfasd");
arr.add(123);
arr.add(3L);
System.out.println(arr);
}
}
运行结果如下:
end