暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

List集合指定泛型后就只能添加一种类型吗?

木木木的小屋 2020-06-14
718

之前也是没想过这方面的问题,都是常规使用。但是最近在看面试题的时候提到了泛型擦除,从而可以实现就算List
集合指定泛型后,仍然可以添加别的数据类型。

聊怎么添加不同数据类型之前,先聊聊泛型擦除是个什么东西。

那么泛型擦除是什么呢?

Java泛型(generics)是在JDK5的时候引入的一个新的特性,泛型提供了编译时类型安全监测机制,该机制允许程序员在编译时监测非法类型。泛型的本质是参数化类型,就是说,所操作的数据类型被指定为一个参数,传入什么参数,就是什么类型。

Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型数据信息都会被擦除掉,这也就是泛型擦除。

举例:List<String>
在经过泛型擦除后就变为了List

可以想象到,本来指定好的数据类型,在编译后被擦除掉了,那么也就是没有了数据类型,没有数据类型,那么它就是一个原始类型,成为了原始类型,就会被使用Object进行替换。从而在Class文件中显示的数据类型就是Object类型。Object又是所有类的根基类,从而可以实现在集合中添加任意数据类型。

其实想要储存不同的数据类型也很简单,只要指定泛型类型为Object就行,但是本文讨论的是在指定了别的数据类型之后,比如Integer或者String类型后,依旧添加不同的数据类型。

泛型提供了在编译时安全监测的功能,监测非法的数据类型,所以常规的add添加数据,行不通,在编译时会被监测出来,从而报错。所以我们需要从别的角度出发,进行不同类型的数据添加。比如使用反射。

try {
// 创建普通List集合,指定类型为String
List<String> strings = new ArrayList<>();
// 常规添加数据
strings.add("啥也不会的程序员");
// 通过反射添加不同的数据类型
// 获取class,然后获取add方法,最后调用invoke添加不同的数据类型
strings.getClass().getMethod("add",Object.class).invoke(strings,new Date());
strings.getClass().getMethod("add",Object.class).invoke(strings,new Object());
strings.getClass().getMethod("add",Object.class).invoke(strings,new ArrayList<>());
System.out.println(strings);
} catch (Exception e) {
e.printStackTrace();
}

本篇文章是根据个人理解书写,如果有不对的地方还请各位大佬指点纠正。

文章转载自木木木的小屋,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论